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, std::enable_if_t<MeshTrait<MeshType>::is_mesh(),
bool> =
true>
43 using Index =
typename MeshType::Index;
44 const Index num_vertices = mesh.get_num_vertices();
46 mesh.initialize_edge_data();
47 std::vector<Index> boundary_next(num_vertices, invalid<Index>());
49 const Index num_edges = mesh.get_num_edges();
50 for (
auto ei :
range(num_edges)) {
51 if (mesh.is_boundary_edge(ei)) {
52 const auto edge = mesh.get_edge_vertices(ei);
53 if (boundary_next[edge[0]] != invalid<Index>() && boundary_next[edge[0]] != edge[1]) {
54 throw std::runtime_error(
"The boundary loops are not simple.");
56 boundary_next[edge[0]] = edge[1];
60 std::vector<std::vector<Index>> bd_loops;
62 for (Index i = 0; i < num_vertices; i++) {
63 if (boundary_next[i] != invalid<Index>()) {
64 bd_loops.emplace_back();
65 auto& loop = bd_loops.back();
68 loop.push_back(curr_idx);
69 while (boundary_next[curr_idx] != invalid<Index>()) {
70 loop.push_back(boundary_next[curr_idx]);
71 boundary_next[curr_idx] = invalid<Index>();
72 curr_idx = loop.back();
74 assert(!loop.empty());
75 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