add some comments

This commit is contained in:
papush! 2021-11-30 11:28:24 +01:00
parent dac20b6f38
commit a9e0f9612b
1 changed files with 31 additions and 12 deletions

View File

@ -10,27 +10,30 @@
/*
vα/--\
/ ------\ vi
/ ---X
/ /---- / \
/ /--- / -\
/ /---- / \
vj --- | \
\-- / -\
\- / /--\
\-- / /-------
\-+---
vα/--\
/ ------\ vi
/ ---X
/ /---- / \
/ /--- / -\
/ /---- / \
vj --- | \
\-- / -\
\- / /--\
\-- / /-------
\-+---
*/
/* Poids pour le laplacien uniforme, constant à 1. */
double uniform_weight(MyMesh &mesh, HalfedgeHandle vi_vj) {
(void) mesh;
(void) vi_vj;
return 1;
}
/* Masse pour le laplacien uniforme, 1 / taille(N1(vi)). */
double uniform_mass(MyMesh &mesh, VertexHandle vi) {
double count = 0;
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. */
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));
HalfedgeHandle vj_vb = mesh.next_halfedge_handle(vi_vj);
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 area = barycentric_vertex_area(mesh, vi);
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)) {
compute_face_areas(mesh);
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;
double sum = 0;
for (HalfedgeHandle vi_vj : mesh.voh_range(vi)) {
// For each outgoing halfedge
VertexHandle vj = mesh.to_vertex_handle(vi_vj);
double halfedge_weight = edge_weight(mesh, vi_vj);
weight.insert(vi.idx(), vj.idx()) = halfedge_weight;
sum -= halfedge_weight;
}
// weight(i, i) = -Σ(j in N1(i)) weight(i, j)
weight.insert(vi.idx(), vi.idx()) = sum;
mass.insert(vi.idx(), vi.idx()) = vertex_mass(mesh, vi);
}
return mass * weight;
}
/* Adoucissement du maillage. */
void smooth(MyMesh &mesh, SmoothingMethod method, double cotan_factor) {
// Calcul de la matrice laplacienne en fonction de la méthode choisie.
double factor;
Eigen::SparseMatrix<qreal> laplacian;
if (method == SmoothingMethod::COTANGENT) {
@ -119,7 +131,10 @@ void smooth(MyMesh &mesh, SmoothingMethod method, double cotan_factor) {
factor = 1;
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();
Eigen::VectorX<qreal> X(n_verts), Y(n_verts), Z(n_verts);
for (VertexHandle vert : mesh.vertices()) {
@ -130,9 +145,13 @@ void smooth(MyMesh &mesh, SmoothingMethod method, double cotan_factor) {
Y(id) = p[1];
Z(id) = p[2];
}
// Application du laplacien pour calculer les décalages.
X = laplacian * X;
Y = laplacian * Y;
Z = laplacian * Z;
// Application des décalages.
for (VertexHandle vert : mesh.vertices()) {
if (mesh.is_boundary(vert)) continue;
size_t id = vert.idx();