add some comments

This commit is contained in:
papush! 2021-11-30 11:28:24 +01:00
parent dac20b6f38
commit a9e0f9612b

View File

@ -25,12 +25,15 @@
*/ */
/* Poids pour le laplacien uniforme, constant à 1. */
double uniform_weight(MyMesh &mesh, HalfedgeHandle vi_vj) { double uniform_weight(MyMesh &mesh, HalfedgeHandle vi_vj) {
(void) mesh; (void) mesh;
(void) vi_vj; (void) vi_vj;
return 1; return 1;
} }
/* Masse pour le laplacien uniforme, 1 / taille(N1(vi)). */
double uniform_mass(MyMesh &mesh, VertexHandle vi) { double uniform_mass(MyMesh &mesh, VertexHandle vi) {
double count = 0; double count = 0;
for (VertexHandle v : mesh.vv_range(vi)) { for (VertexHandle v : mesh.vv_range(vi)) {
@ -43,6 +46,7 @@ double uniform_mass(MyMesh &mesh, VertexHandle vi) {
/* Calcule le poids cotangent pour l'arête reliant vi à vj. */ /* Calcule le poids cotangent pour l'arête reliant vi à vj. */
double cotangent_weight(MyMesh &mesh, HalfedgeHandle vi_vj) { double cotangent_weight(MyMesh &mesh, HalfedgeHandle vi_vj) {
// Voir le graphique en haut de ce fichier.
Point pj = mesh.point(mesh.to_vertex_handle(vi_vj)); Point pj = mesh.point(mesh.to_vertex_handle(vi_vj));
HalfedgeHandle vj_vb = mesh.next_halfedge_handle(vi_vj); HalfedgeHandle vj_vb = mesh.next_halfedge_handle(vi_vj);
Point pb = mesh.point(mesh.to_vertex_handle(vj_vb)); Point pb = mesh.point(mesh.to_vertex_handle(vj_vb));
@ -82,12 +86,15 @@ double barycentric_vertex_area(MyMesh &mesh, VertexHandle vert) {
} }
/* Fonction de masse pour le laplacien cotangent. */
double cotangent_mass(MyMesh &mesh, VertexHandle vi) { double cotangent_mass(MyMesh &mesh, VertexHandle vi) {
double area = barycentric_vertex_area(mesh, vi); double area = barycentric_vertex_area(mesh, vi);
return 1. / (2 * area); return 1. / (2 * area);
} }
/* Calcule la matrice laplacienne avec les fonctions de poids d'arête
* et de masse de sommet spécifiées par l'utilisatrice. */
Eigen::SparseMatrix<qreal> laplacian_matrix(MyMesh &mesh, double (*edge_weight)(MyMesh &, HalfedgeHandle), double (*vertex_mass)(MyMesh &, VertexHandle)) { Eigen::SparseMatrix<qreal> laplacian_matrix(MyMesh &mesh, double (*edge_weight)(MyMesh &, HalfedgeHandle), double (*vertex_mass)(MyMesh &, VertexHandle)) {
compute_face_areas(mesh); compute_face_areas(mesh);
size_t n_verts = mesh.n_vertices(); size_t n_verts = mesh.n_vertices();
@ -97,19 +104,24 @@ Eigen::SparseMatrix<qreal> laplacian_matrix(MyMesh &mesh, double (*edge_weight)(
if (mesh.is_boundary(vi)) continue; if (mesh.is_boundary(vi)) continue;
double sum = 0; double sum = 0;
for (HalfedgeHandle vi_vj : mesh.voh_range(vi)) { for (HalfedgeHandle vi_vj : mesh.voh_range(vi)) {
// For each outgoing halfedge
VertexHandle vj = mesh.to_vertex_handle(vi_vj); VertexHandle vj = mesh.to_vertex_handle(vi_vj);
double halfedge_weight = edge_weight(mesh, vi_vj); double halfedge_weight = edge_weight(mesh, vi_vj);
weight.insert(vi.idx(), vj.idx()) = halfedge_weight; weight.insert(vi.idx(), vj.idx()) = halfedge_weight;
sum -= halfedge_weight; sum -= halfedge_weight;
} }
// weight(i, i) = -Σ(j in N1(i)) weight(i, j)
weight.insert(vi.idx(), vi.idx()) = sum; weight.insert(vi.idx(), vi.idx()) = sum;
mass.insert(vi.idx(), vi.idx()) = vertex_mass(mesh, vi); mass.insert(vi.idx(), vi.idx()) = vertex_mass(mesh, vi);
} }
return mass * weight; return mass * weight;
} }
/* Adoucissement du maillage. */
void smooth(MyMesh &mesh, SmoothingMethod method, double cotan_factor) { void smooth(MyMesh &mesh, SmoothingMethod method, double cotan_factor) {
// Calcul de la matrice laplacienne en fonction de la méthode choisie.
double factor; double factor;
Eigen::SparseMatrix<qreal> laplacian; Eigen::SparseMatrix<qreal> laplacian;
if (method == SmoothingMethod::COTANGENT) { if (method == SmoothingMethod::COTANGENT) {
@ -119,7 +131,10 @@ void smooth(MyMesh &mesh, SmoothingMethod method, double cotan_factor) {
factor = 1; factor = 1;
laplacian = laplacian_matrix(mesh, uniform_weight, uniform_mass); laplacian = laplacian_matrix(mesh, uniform_weight, uniform_mass);
} }
// laplacian = laplacian * laplacian;
laplacian = laplacian * laplacian; // Mise au carré.
// Transfert des coordonées de chaque point dans une matrice.
size_t n_verts = mesh.n_vertices(); size_t n_verts = mesh.n_vertices();
Eigen::VectorX<qreal> X(n_verts), Y(n_verts), Z(n_verts); Eigen::VectorX<qreal> X(n_verts), Y(n_verts), Z(n_verts);
for (VertexHandle vert : mesh.vertices()) { for (VertexHandle vert : mesh.vertices()) {
@ -130,9 +145,13 @@ void smooth(MyMesh &mesh, SmoothingMethod method, double cotan_factor) {
Y(id) = p[1]; Y(id) = p[1];
Z(id) = p[2]; Z(id) = p[2];
} }
// Application du laplacien pour calculer les décalages.
X = laplacian * X; X = laplacian * X;
Y = laplacian * Y; Y = laplacian * Y;
Z = laplacian * Z; Z = laplacian * Z;
// Application des décalages.
for (VertexHandle vert : mesh.vertices()) { for (VertexHandle vert : mesh.vertices()) {
if (mesh.is_boundary(vert)) continue; if (mesh.is_boundary(vert)) continue;
size_t id = vert.idx(); size_t id = vert.idx();