J'ai amélioré la documentation de libigl qui se trouve ici : https://profs.etsmtl.ca/epaquette/share/libigl/
Je mets en évidence les différences plus bas.
MatrixXi F; // Matrice <nombre de triangles> x 3 qui contient les indices des sommets.
// #F = nombre de triangles
MatrixXd V; // Matrice <nombre de sommets> x 3 qui contient les coordonnées XYZ des sommets.
// #V = nombre de sommets
// #E = nombre d'arêtes
adjacency_list.h // Adjacence des sommets entre eux par rapport au graphe des arêtes // Préparation de vecteurs où libigl va écrire le résultat : std::vector<std::vector<int> > al; // Vecteur de vecteur. Le vecteur englobant est de taille al.size() == #V. // Le vecteur inclus al[vi] contient les indices des sommets adjacents (partageant une arête) // avec le sommet vi. // al[vi].size() correspond au nombre de sommets adjacents au sommet vi. bool sorted = true; // Ajuster "sorted" selon si on veut que les faces soient triées ou pas (en ordre // anti-horaire autour du sommet). // ATTENTION : Si la liste "sorted=true" est demandée, la liste des sommets pourrait être erronée // si le sommet fait partie d'un segment non-manifold ou s'il y a des faces mal orientées. adjacency_list(F, al, sorted);
edges.h // Préparation de matrices et tableaux où libigl va écrire le résultat : Eigen::MatrixXi E; // Matrice #E x 2 contenant les arêtes uniques. Les colonnes indiquent les numéros de sommets. edges(F, E); is_boundary_edge.h Eigen::Array<bool,Eigen::Dynamic,1> BoolBoundary; // Pourrait aussi utiliser int à la place de bool. // Le tableau des arêtes E (#E x 2) doit être fourni en entrée. // Pourrait utiliser edges.h, is_edge_manifold.h, ou unique_edge_map.h pour calculer E. is_boundary_edge(E, F, BoolBoundary);
is_edge_manifold.h // Préparation de matrices et tableaux où libigl va écrire le résultat : Eigen::Array<bool, Eigen::Dynamic, Eigen::Dynamic> BF; // Tableau #F x 3 // Chaque ligne correspond à un triangle. // Chaque colonne fait référence à l'arête opposée au sommet correspondant du triangle. // L'entrée indique si l'arête en question est manifold ou pas. Eigen::MatrixXi E; // Tableau #E x 2 contenant les arêtes uniques. Les colonnes indiquent les numéros de sommets. // Ressemble à la sortie de edges.h et unique_edge_map.h Eigen::VectorXi EMAP; // Liste (#F*3) x 1 qui donne l'indice d'une arête (le numéro de ligne dans E). // Les #F premières lignes, correspondent à l'indice de l'arête opposée aux sommets 0 de chaque triangle. // Les #F lignes suivantes correspondent à l'indice de l'arête opposée aux sommets 1 de chaque triangle. // Les #F lignes suivantes correspondent à l'indice de l'arête opposée aux sommets 2 de chaque triangle. // L'indice de l'arête est pour le tableau des arêtes E. Eigen::Array<bool, Eigen::Dynamic, 1> BoolManifold; // Tableau #E x 1. Chaque entrée indique si l'arête correspondante dans E est manifold ou pas. // Dans les Array ci-haut, pourrait aussi utiliser int à la place de bool. is_edge_manifold(F, BF, E, EMAP, BoolManifold); vertex_triangle_adjacency.h // Préparation de vecteurs où libigl va écrire le résultat : vector<vector<int> > VF; // Liste de listes. Liste englobante est de longueur #V, c'est à dire VF.size == #V // Chaque liste inclue dans la liste englobante, c'est à dire VF[vi] a une taille // qui correspond au nombre de faces adjacentes à ce sommet vi. // Chaque entrée VF[vi][j] correspond à l'indice de la jème face autour du sommet vi. vector<vector<int> > VFi; // Liste de listes. Liste englobante est de longueur #V, c'est à dire VF.size == #V // Chaque liste inclue dans la liste englobante, c'est à dire VFi[vi] a une taille // qui correspond au nombre de faces adjacentes à ce sommet vi. // Chaque entrée VFi[vi][j] correspond à l'indice (0, 1, ou 2) du sommet vi dans la // liste des sommets F.row(VF[vi][j]) de la face VF[vi][j]. vertex_triangle_adjacency(V.rows(), F, VF, VFi); // Pour savoir combien de faces adjacentes il y a pour le somet vi : VF[vi].size(); // Pour le sommet vi, on peut consulter la jème face comme ceci : VF[vi][j]