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>
41std::enable_if_t<MeshTrait<MeshType>::is_mesh(), std::vector<std::vector<typename MeshType::Index>>>
43{
44 using Index = typename MeshType::Index;
45 const Index num_vertices = mesh.get_num_vertices();
46
47 mesh.initialize_edge_data();
48 std::vector<Index> boundary_next(num_vertices, invalid<Index>());
49
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.");
56 }
57 boundary_next[edge[0]] = edge[1];
58 }
59 }
60
61 std::vector<std::vector<Index>> bd_loops;
62 bd_loops.reserve(4);
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();
67
68 Index curr_idx = i;
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();
74 }
75 assert(!loop.empty());
76 assert(loop.front() == loop.back());
77 }
78 }
79 return bd_loops;
80}
81} // namespace legacy
82} // 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