Compare commits

..

4 Commits

Author SHA1 Message Date
b44bad92e7 improve the implicit surface approximation
by scaling the normals based on the mesh size
2022-01-10 00:15:07 +01:00
d359075c64 stop updating values continuously as sliders are dragged 2022-01-10 00:14:17 +01:00
a59b494758 update readme 2022-01-10 00:14:12 +01:00
228096c1a6 improve mesh view handling 2022-01-10 00:13:49 +01:00
9 changed files with 47 additions and 14 deletions

View File

@ -6,14 +6,15 @@ Ceci comprend les fonctionalités suivantes :
- analyse de courbure (dans src/curvature.cpp) - analyse de courbure (dans src/curvature.cpp)
- adoucissement d'un maillage par laplacien uniforme ou cotangent (dans - adoucissement d'un maillage par laplacien uniforme ou cotangent (dans
src/smoothing.cpp) src/smoothing.cpp)
- suppression de parasites (dans src/noise_removal.cpp)
Des maillages exemples sont inclus, data/gargoyle_trou.obj est un Des maillages exemples sont inclus, data/gargoyle_trou.obj est un
bon exemple pour le remplissage, data/bunnyLowPoly-noisy.obj pour bon exemple pour le remplissage, data/bunnyLowPoly-noisy.obj pour
l'adoucissement. l'adoucissement et data/bunny.obj pour la suppression de parasites.
Compilation Compilation
cmake -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS=-O2 cmake -Bbuild -DCMAKE_BUILD_TYPE=Release
puis puis
cmake --build build cmake --build build

View File

@ -46,6 +46,7 @@ DoubleInput::DoubleInput(QObject *parent, double min, double max,
_spin_box->setValue(value); _spin_box->setValue(value);
_slider->setMaximum(_slider_resolution); _slider->setMaximum(_slider_resolution);
_slider->setValue(doubleToInt(value)); _slider->setValue(doubleToInt(value));
_slider->setTracking(false);
connect(_slider, &QSlider::valueChanged, connect(_slider, &QSlider::valueChanged,
this, &DoubleInput::onSliderValueChanged); this, &DoubleInput::onSliderValueChanged);
connect(_spin_box, QOverload<double>::of(&QDoubleSpinBox::valueChanged), connect(_spin_box, QOverload<double>::of(&QDoubleSpinBox::valueChanged),

View File

@ -2,6 +2,7 @@
#include "IO.h" #include "IO.h"
#include "util.h" #include "util.h"
#include <MeshReconstruction.h> #include <MeshReconstruction.h>
#include <OpenMesh/Core/Utils/PropertyManager.hh>
static std::vector<std::vector<HalfedgeHandle>> findHoles(MyMesh &mesh) { static std::vector<std::vector<HalfedgeHandle>> findHoles(MyMesh &mesh) {
@ -153,7 +154,7 @@ vector<MyMesh::VertexHandle> Hole_Filling::next_neighbors(const vector<MyMesh::V
// ***** Computation of RBF // ***** Computation of RBF
pair<pair<Eigen::MatrixXd &, Eigen::VectorXd &>, vector<MyMesh::Point> &> Hole_Filling::compute_approx_mat(vector<MyMesh::VertexHandle> vlist) pair<pair<Eigen::MatrixXd &, Eigen::VectorXd &>, vector<MyMesh::Point> &> Hole_Filling::compute_approx_mat(vector<MyMesh::VertexHandle> vlist, double normal_scale)
{ {
const int n(vlist.size()), d(10) ; const int n(vlist.size()), d(10) ;
Eigen::MatrixXd & A = *(new Eigen::MatrixXd(3*n+d,3*n+d)) ; Eigen::MatrixXd & A = *(new Eigen::MatrixXd(3*n+d,3*n+d)) ;
@ -170,12 +171,12 @@ pair<pair<Eigen::MatrixXd &, Eigen::VectorXd &>, vector<MyMesh::Point> &> Hole_F
//Append vertices+normals to pts_list //Append vertices+normals to pts_list
for (int i=0; i<n; i++) for (int i=0; i<n; i++)
{ {
pts_list.push_back(_mesh.point(vlist.at(i)) + _mesh.normal(vlist.at(i))) ; pts_list.push_back(_mesh.point(vlist.at(i)) + _mesh.normal(vlist.at(i)) * normal_scale) ;
} }
//Append vertices-normals to pts_list //Append vertices-normals to pts_list
for (int i=0; i<n; i++) for (int i=0; i<n; i++)
{ {
pts_list.push_back(_mesh.point(vlist.at(i)) - _mesh.normal(vlist.at(i))) ; pts_list.push_back(_mesh.point(vlist.at(i)) - _mesh.normal(vlist.at(i)) * normal_scale) ;
} }
int nn = pts_list.size() ; int nn = pts_list.size() ;
@ -302,15 +303,37 @@ Mesh Hole_Filling::poly_n_out(const Implicit_RBF &implicit, Rect3 domain)
} }
/* Computes a mesh's bounding box and stores it in a mesh property
* named "bounding_box". */
static void computeMeshBoundingBox(MyMesh &mesh, Hole_Filling &hf) {
try {
auto mesh_bb = OpenMesh::getProperty<void, Rect3>
(mesh, "bounding_box");
} catch (const std::runtime_error &e) {
auto mesh_bb = OpenMesh::getOrMakeProperty<void, Rect3>
(mesh, "bounding_box");
std::vector<VertexHandle> verts;
for (VertexHandle vh : mesh.vertices()) {
verts.push_back(vh);
}
*mesh_bb = hf.estimate_BB(verts);
}
}
MyMesh fillHoleImplicit(MyMesh &mesh, Hole_Filling &hf, MyMesh fillHoleImplicit(MyMesh &mesh, Hole_Filling &hf,
std::vector<HalfedgeHandle> &hole) { std::vector<HalfedgeHandle> &hole) {
computeMeshBoundingBox(mesh, hf);
Rect3 mesh_bb = *OpenMesh::getProperty<void, Rect3>(mesh, "bounding_box");
double diag = mesh_bb.size.Norm();
std::vector<VertexHandle> verts; std::vector<VertexHandle> verts;
for (HalfedgeHandle hh : hole) { for (HalfedgeHandle hh : hole) {
verts.push_back(mesh.to_vertex_handle(hh)); verts.push_back(mesh.to_vertex_handle(hh));
} }
auto bb = hf.estimate_BB(verts) ; auto bb = hf.estimate_BB(verts) ;
verts = hf.next_neighbors(verts); verts = hf.next_neighbors(verts);
auto [system, pts_list] = hf.compute_approx_mat(verts); auto [system, pts_list] = hf.compute_approx_mat(verts, diag * .1);
auto [alpha, beta] = hf.solve_approx(system, pts_list.size(), 10); auto [alpha, beta] = hf.solve_approx(system, pts_list.size(), 10);
Implicit_RBF rbf(alpha, beta, pts_list); Implicit_RBF rbf(alpha, beta, pts_list);

View File

@ -103,7 +103,7 @@ public:
vector<MyMesh::VertexHandle> next_neighbors(const vector<MyMesh::VertexHandle> & bnd) ; vector<MyMesh::VertexHandle> next_neighbors(const vector<MyMesh::VertexHandle> & bnd) ;
// Computation of RBF // Computation of RBF
pair<pair<Eigen::MatrixXd &,Eigen::VectorXd &>,vector<MyMesh::Point> &> compute_approx_mat(vector<MyMesh::VertexHandle> vlist) ; pair<pair<Eigen::MatrixXd &,Eigen::VectorXd &>,vector<MyMesh::Point> &> compute_approx_mat(vector<MyMesh::VertexHandle> vlist, double normal_scale=1) ;
pair<vector<float>&, vector<float>&> solve_approx(const pair<Eigen::MatrixXd &, Eigen::VectorXd &> &p, int n, int d) ; pair<vector<float>&, vector<float>&> solve_approx(const pair<Eigen::MatrixXd &, Eigen::VectorXd &> &p, int n, int d) ;
// IO // IO

View File

@ -32,6 +32,7 @@ MeshProcessor::MeshProcessor(const QString &path, MeshViewer &mesh_viewer,
qWarning() << "Curvature computation failed"; qWarning() << "Curvature computation failed";
} }
connect(&mesh_viewer, &MeshViewer::clicked, this, &MeshProcessor::click); connect(&mesh_viewer, &MeshViewer::clicked, this, &MeshProcessor::click);
updateView(); updateView();
} }
@ -44,7 +45,7 @@ MeshProcessor::~MeshProcessor() {
} }
void MeshProcessor::updateView() const { void MeshProcessor::updateView() {
if (mesh_viewer.isInitialized()) { if (mesh_viewer.isInitialized()) {
mesh_viewer.removeMesh(mesh); mesh_viewer.removeMesh(mesh);
mesh_viewer.addMesh(mesh); mesh_viewer.addMesh(mesh);

View File

@ -18,7 +18,7 @@ class MeshProcessor : public QObject {
double implicit_hole_filling_discr; double implicit_hole_filling_discr;
std::vector<MyMesh> fillings; std::vector<MyMesh> fillings;
void updateView() const; void updateView();
public: public:
MyMesh mesh; MyMesh mesh;

View File

@ -89,9 +89,10 @@ void MeshViewer::paintGL() {
} }
void MeshViewer::addMesh(const MyMesh &mesh) { void MeshViewer::addMesh(MyMesh &mesh) {
Q_ASSERT(isValid()); Q_ASSERT(isValid());
makeCurrent(); makeCurrent();
mesh.viewer_id = meshes.size();
meshes.emplace_back(mesh, program); meshes.emplace_back(mesh, program);
doneCurrent(); doneCurrent();
update(); update();
@ -100,9 +101,14 @@ void MeshViewer::addMesh(const MyMesh &mesh) {
void MeshViewer::removeMesh(const MyMesh &mesh) { void MeshViewer::removeMesh(const MyMesh &mesh) {
makeCurrent(); makeCurrent();
meshes.remove_if([&](const MeshView &mv) { size_t i = 0;
return &mv.mesh == &mesh; for (auto it = meshes.begin(); it != meshes.end(); ++it) {
}); if (i == mesh.viewer_id) {
meshes.erase(it);
break;
}
i++;
}
doneCurrent(); doneCurrent();
update(); update();
} }

View File

@ -46,7 +46,7 @@ public:
constexpr bool isInitialized() { return is_initialized; } constexpr bool isInitialized() { return is_initialized; }
public slots: public slots:
void addMesh(const MyMesh &mesh); void addMesh(MyMesh &mesh);
void removeMesh(const MyMesh &mesh); void removeMesh(const MyMesh &mesh);
void updateForReal(); void updateForReal();

View File

@ -25,6 +25,7 @@ class MyMesh : public OpenMesh::TriMesh_ArrayKernelT<MyTraits> {
public: public:
Color default_color {.5, .5, .5}; Color default_color {.5, .5, .5};
QMatrix4x4 transform; QMatrix4x4 transform;
size_t viewer_id;
std::vector<std::vector<HalfedgeHandle>> holes; std::vector<std::vector<HalfedgeHandle>> holes;
}; };