18#include <lagrange/MeshTrait.h>
19#include <lagrange/common.h>
20#include <lagrange/legacy/inline.h>
21#include <lagrange/utils/range.h>
27template <
typename Index>
31 std::vector<Index> facet_to_component;
33 std::vector<std::vector<Index>> component_to_facets;
51template <
typename MeshType>
54 const std::vector<bool>& is_edge_passable)
57 using Index =
typename MeshType::Index;
60 la_runtime_assert(mesh.is_edge_data_initialized(),
"Edge data is not initialized");
61 la_runtime_assert(safe_cast<Index>(is_edge_passable.size()) == mesh.get_num_edges());
63 std::vector<Index> facet_component_ids(mesh.get_num_facets(), invalid<Index>());
65 auto perform_bfs = [&](
const Index seed_id,
const Index component_id) {
66 assert(facet_component_ids[seed_id] == invalid<Index>());
67 std::deque<Index> search_queue;
68 search_queue.push_back(seed_id);
69 while (!search_queue.empty()) {
70 const auto candidate_id = search_queue.back();
71 search_queue.pop_back();
72 if (facet_component_ids[candidate_id] == invalid<Index>()) {
73 facet_component_ids[candidate_id] = component_id;
74 for (Index ci :
range(mesh.get_vertex_per_facet())) {
75 const auto edge_id = mesh.get_edge(candidate_id, ci);
76 const bool is_passable = is_edge_passable[edge_id];
78 mesh.foreach_facets_around_edge(edge_id, [&](Index f) {
79 if (f != candidate_id) {
80 search_queue.push_back(f);
90 Index num_components = 0;
91 for (
auto i :
range(mesh.get_num_facets())) {
92 if (facet_component_ids[i] == invalid<Index>()) {
93 perform_bfs(i, num_components);
98 num_components > 0 || mesh.get_num_facets() == 0,
99 "Extracted " + std::to_string(num_components) +
" comps out of " +
100 std::to_string(mesh.get_num_facets()) +
" facets");
102 std::vector<std::vector<Index>> component_to_facets(num_components);
103 std::vector<Index> num_component_facets(num_components, 0);
104 for (
auto i :
range(mesh.get_num_facets())) {
105 const auto component_id = facet_component_ids[i];
106 ++num_component_facets[component_id];
108 for (
auto i :
range(num_components)) {
109 component_to_facets[i].reserve(num_component_facets[i]);
111 for (
auto i :
range(mesh.get_num_facets())) {
112 const auto component_id = facet_component_ids[i];
113 component_to_facets[component_id].push_back(i);
117 ComputeBorderedComponentsOutput<Index> output;
118 output.facet_to_component.swap(facet_component_ids);
119 output.component_to_facets.swap(component_to_facets);
#define la_runtime_assert(...)
Runtime assertion check.
Definition: assert.h:169
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
MeshTrait class provide compiler check for different mesh types.
Definition: MeshTrait.h:108
Definition: compute_bordered_components.h:29