add some comments
This commit is contained in:
parent
dac20b6f38
commit
a9e0f9612b
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user