Lagrange
Components.h
1/*
2 * Copyright 2017 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 <queue>
15#include <vector>
16
17#include <lagrange/Connectivity.h>
18#include <lagrange/MeshGeometry.h>
19#include <lagrange/common.h>
20#include <lagrange/legacy/inline.h>
21#include <lagrange/utils/safe_cast.h>
22
23namespace lagrange {
24LAGRANGE_LEGACY_INLINE
25namespace legacy {
26
27template <typename GeometryType>
29{
30public:
31 using Index = typename GeometryType::Index;
32 using IndexList = typename Connectivity<GeometryType>::IndexList;
33
34 void initialize(GeometryType& geometry, Connectivity<GeometryType>* conn = nullptr)
35 {
36 std::unique_ptr<Connectivity<GeometryType>> temporary_conn_ptr = nullptr;
37
38 if (!conn) {
39 temporary_conn_ptr = compute_connectivity<GeometryType>(geometry);
40 conn = temporary_conn_ptr.get();
41 }
42
43 m_components.clear();
44 const auto num_facets = geometry.get_num_facets();
45 std::vector<bool> visited(num_facets, false);
46 for (Index i = 0; i < num_facets; i++) {
47 if (visited[i]) continue;
48 m_components.emplace_back();
49 auto& comp = m_components.back();
50
51 std::queue<Index> Q;
52 Q.push(i);
53 visited[i] = true;
54 while (!Q.empty()) {
55 Index f = Q.front();
56 Q.pop();
57 comp.push_back(f);
58
59 const auto& adj_facets = conn->get_facets_adjacent_to_facet(f);
60 for (const Index& adj_f : adj_facets) {
61 if (!visited[adj_f]) {
62 Q.push(adj_f);
63 visited[adj_f] = true;
64 }
65 }
66 }
67 }
68
69 m_per_facet_component_ids.resize(num_facets);
70 Index comp_id = 0;
71 for (const auto& comp : m_components) {
72 for (const auto fid : comp) {
73 m_per_facet_component_ids[fid] = comp_id;
74 }
75 comp_id++;
76 }
77 }
78
79 const std::vector<IndexList>& get_components() const { return m_components; }
80
81 const IndexList& get_per_facet_component_ids() const { return m_per_facet_component_ids; }
82
83 Index get_num_components() const { return safe_cast<Index>(m_components.size()); }
84
85protected:
86 std::vector<IndexList> m_components;
87 IndexList m_per_facet_component_ids;
88};
89
90template <typename GeometryType>
91std::unique_ptr<Components<GeometryType>> compute_components(
92 const GeometryType& geometry,
93 Connectivity<GeometryType>* conn = nullptr)
94{
95 auto ptr = std::make_unique<Components<GeometryType>>();
96
97 ptr->initialize(geometry, conn);
98 return ptr;
99}
100
101} // namespace legacy
102} // namespace lagrange
Definition: Connectivity.h:23
Definition: Components.h:29
size_t compute_components(SurfaceMesh< Scalar, Index > &mesh, ComponentOptions options={})
Compute connected components of an input mesh.
Definition: compute_components.cpp:99
Main namespace for Lagrange.
Definition: AABBIGL.h:30