Lagrange
Connectivity.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 <algorithm>
15#include <vector>
16
17#include <lagrange/MeshGeometry.h>
18#include <lagrange/utils/assert.h>
19
20namespace lagrange {
21template <typename GeometryType>
23{
24public:
25 using Index = typename GeometryType::Index;
26 using IndexList = std::vector<Index>;
27 using AdjacencyList = std::vector<IndexList>;
28
30 : m_initialized(false)
31 {}
32
33 void initialize(const GeometryType& geometry)
34 {
35 m_v2v.clear();
36 m_v2f.clear();
37 m_f2f.clear();
38
39 auto remove_duplicate_entries = [](IndexList& arr) {
40 std::sort(arr.begin(), arr.end());
41 const auto end_itr = std::unique(arr.begin(), arr.end());
42 arr.resize(std::distance(arr.begin(), end_itr));
43 };
44
45 auto extract_duplicate_entries = [](IndexList& arr) {
46 std::sort(arr.begin(), arr.end());
47 IndexList duplicate_entries;
48 Index curr = arr.back() + 1;
49 for (const auto& item : arr) {
50 if (curr == item &&
51 (duplicate_entries.empty() || item != duplicate_entries.back())) {
52 duplicate_entries.push_back(item);
53 } else {
54 curr = item;
55 }
56 }
57 arr.swap(duplicate_entries);
58 };
59
60 const Index num_vertices = geometry.get_num_vertices();
61 const Index num_facets = geometry.get_num_facets();
62 const Index vertex_per_facet = geometry.get_vertex_per_facet();
63 m_v2v.resize(num_vertices);
64 m_v2f.resize(num_vertices);
65 m_f2f.resize(num_facets);
66 for (auto& arr : m_v2v) arr.reserve(16);
67 for (auto& arr : m_v2f) arr.reserve(16);
68 for (auto& arr : m_f2f) arr.reserve(16);
69
70 const auto& facets = geometry.get_facets();
71
72 for (Index i = 0; i < num_facets; i++) {
73 for (Index j = 0; j < vertex_per_facet; j++) {
74 Index curr = facets(i, j);
75 Index next = facets(i, (j + 1) % vertex_per_facet);
76 Index prev = facets(i, (j + vertex_per_facet - 1) % vertex_per_facet);
77 m_v2v[curr].push_back(next);
78 m_v2v[curr].push_back(prev);
79 m_v2f[curr].push_back(i);
80 }
81 }
82 std::for_each(m_v2v.begin(), m_v2v.end(), remove_duplicate_entries);
83 std::for_each(m_v2f.begin(), m_v2f.end(), remove_duplicate_entries);
84
85 for (Index i = 0; i < num_facets; i++) {
86 for (Index j = 0; j < vertex_per_facet; j++) {
87 Index vi = facets(i, j);
88 const auto& adj_facets = m_v2f[vi];
89 m_f2f[i].insert(m_f2f[i].end(), adj_facets.begin(), adj_facets.end());
90 }
91 }
92 std::for_each(m_f2f.begin(), m_f2f.end(), extract_duplicate_entries);
93
94 // Remove self from f2f adjacency.
95 for (Index i = 0; i < num_facets; i++) {
96 const auto itr = std::find(m_f2f[i].begin(), m_f2f[i].end(), i);
97 la_runtime_assert(itr != m_f2f[i].end());
98 m_f2f[i].erase(itr);
99 }
100
101 m_initialized = true;
102 }
103
104 bool is_initialized() const { return m_initialized; }
105 const AdjacencyList& get_vertex_vertex_adjacency() const { return m_v2v; }
106 const AdjacencyList& get_vertex_facet_adjacency() const { return m_v2f; }
107 const AdjacencyList& get_facet_facet_adjacency() const { return m_f2f; }
108 const IndexList& get_vertices_adjacent_to_vertex(Index vi) const { return m_v2v[vi]; }
109 const IndexList& get_facets_adjacent_to_vertex(Index vi) const { return m_v2f[vi]; }
110 const IndexList& get_facets_adjacent_to_facet(Index fi) const { return m_f2f[fi]; }
111
112protected:
113 bool m_initialized;
114 AdjacencyList m_v2v;
115 AdjacencyList m_v2f;
116 AdjacencyList m_f2f;
117};
118
119template <typename GeometryType>
120std::unique_ptr<Connectivity<GeometryType>> compute_connectivity(const GeometryType& geometry)
121{
122 auto ptr = std::make_unique<Connectivity<GeometryType>>();
123
124 ptr->initialize(geometry);
125
126 return ptr;
127}
128} // namespace lagrange
Definition: Connectivity.h:23
#define la_runtime_assert(...)
Runtime assertion check.
Definition: assert.h:169
Main namespace for Lagrange.
Definition: AABBIGL.h:30