19#include <lagrange/Edge.h>
20#include <lagrange/MeshTrait.h>
21#include <lagrange/common.h>
22#include <lagrange/legacy/inline.h>
23#include <lagrange/utils/range.h>
40template <
typename MeshType>
41std::enable_if_t<MeshTrait<MeshType>::is_mesh(), std::vector<std::vector<typename MeshType::Index>>>
44 using Index =
typename MeshType::Index;
45 const Index num_vertices = mesh.get_num_vertices();
47 mesh.initialize_edge_data();
48 std::vector<Index> boundary_next(num_vertices, invalid<Index>());
50 const Index num_edges = mesh.get_num_edges();
51 for (
auto ei :
range(num_edges)) {
52 if (mesh.is_boundary_edge(ei)) {
53 const auto edge = mesh.get_edge_vertices(ei);
54 if (boundary_next[edge[0]] != invalid<Index>() && boundary_next[edge[0]] != edge[1]) {
55 throw std::runtime_error(
"The boundary loops are not simple.");
57 boundary_next[edge[0]] = edge[1];
61 std::vector<std::vector<Index>> bd_loops;
63 for (Index i = 0; i < num_vertices; i++) {
64 if (boundary_next[i] != invalid<Index>()) {
65 bd_loops.emplace_back();
66 auto& loop = bd_loops.back();
69 loop.push_back(curr_idx);
70 while (boundary_next[curr_idx] != invalid<Index>()) {
71 loop.push_back(boundary_next[curr_idx]);
72 boundary_next[curr_idx] = invalid<Index>();
73 curr_idx = loop.back();
75 assert(!loop.empty());
76 assert(loop.front() == loop.back());
std::vector< std::vector< Index > > extract_boundary_loops(const SurfaceMesh< Scalar, Index > &mesh)
Extract boundary loops from a surface mesh.
Definition: extract_boundary_loops.cpp:24
internal::Range< Index > range(Index end)
Returns an iterable object representing the range [0, end).
Definition: range.h:176
Main namespace for Lagrange.
Definition: AABBIGL.h:30