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)
56 static_assert(MeshTrait<MeshType>::is_mesh(),
"First argument must be Lagrange::Mesh<>.");
57 using Index =
typename MeshType::Index;
60 la_runtime_assert(mesh.is_edge_data_initialized(),
"Edge data is not initialized");
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) {
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();
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;
93 perform_bfs(i, num_components);
99 "Extracted " + std::to_string(num_components) +
" comps out of " +
102 std::vector<std::vector<Index>> component_to_facets(num_components);
103 std::vector<Index> num_component_facets(num_components, 0);
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]);
112 const auto component_id = facet_component_ids[i];
113 component_to_facets[component_id].push_back(i);
118 output.facet_to_component.swap(facet_component_ids);
119 output.component_to_facets.swap(component_to_facets);
Index get_num_facets() const
Retrieves the number of facets.
Definition SurfaceMesh.h:678
#define la_runtime_assert(...)
Runtime assertion check.
Definition assert.h:174
internal::Range< Index > range(Index end)
Returns an iterable object representing the range [0, end).
Definition range.h:176
constexpr T invalid()
You can use invalid<T>() to get a value that can represent "invalid" values, such as invalid indices ...
Definition invalid.h:40
constexpr auto safe_cast(SourceType value) -> std::enable_if_t<!std::is_same< SourceType, TargetType >::value, TargetType >
Perform safe cast from SourceType to TargetType, where "safe" means:
Definition safe_cast.h:50
Main namespace for Lagrange.
Definition compute_bordered_components.h:29