Lagrange
extract_boundary_loops.h
1/*
2 * Copyright 2018 Adobe. All rights reserved.
3 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License. You may obtain a copy
5 * of the License at http://www.apache.org/licenses/LICENSE-2.0
6 *
7 * Unless required by applicable law or agreed to in writing, software distributed under
8 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9 * OF ANY KIND, either express or implied. See the License for the specific language
10 * governing permissions and limitations under the License.
11 */
12#pragma once
13
14#include <cassert>
15#include <exception>
16#include <limits>
17#include <vector>
18
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>
24
25namespace lagrange {
26LAGRANGE_LEGACY_INLINE
27namespace legacy {
28
40template <typename MeshType, std::enable_if_t<MeshTrait<MeshType>::is_mesh(), bool> = true>
41std::vector<std::vector<typename MeshType::Index>> extract_boundary_loops(MeshType& mesh)
42{
43 using Index = typename MeshType::Index;
44 const Index num_vertices = mesh.get_num_vertices();
45
46 mesh.initialize_edge_data();
47 std::vector<Index> boundary_next(num_vertices, invalid<Index>());
48
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.");
55 }
56 boundary_next[edge[0]] = edge[1];
57 }
58 }
59
60 std::vector<std::vector<Index>> bd_loops;
61 bd_loops.reserve(4);
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();
66
67 Index curr_idx = i;
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();
73 }
74 assert(!loop.empty());
75 assert(loop.front() == loop.back());
76 }
77 }
78 return bd_loops;
79}
80} // namespace legacy
81} // namespace lagrange
Definition: Mesh.h:48
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