18#include <unordered_map>
19#include <unordered_set>
21#include <lagrange/common.h>
22#include <lagrange/utils/assert.h>
23#include <lagrange/utils/safe_cast.h>
27template <
typename Index>
49 static EdgeType Invalid() {
return EdgeType(invalid<Index>(), invalid<Index>()); }
53 EdgeType(
const std::array<Index, 2>& arr)
58 inline Index v1()
const {
return m_v1; }
59 inline Index v2()
const {
return m_v2; }
60 inline bool is_valid()
const {
return m_v1 != invalid<Index>() && m_v2 != invalid<Index>(); }
64 this->m_v1 = other.m_v1;
65 this->m_v2 = other.m_v2;
70 this->m_v1 = other.m_v1;
71 this->m_v2 = other.m_v2;
79 return (m_v1 == rhs.m_v1 && m_v2 == rhs.m_v2) || (m_v1 == rhs.m_v2 && m_v2 == rhs.m_v1);
81 bool operator!=(
const EdgeType<Index>& rhs)
const {
return !(*
this == rhs); }
83 Index operator[](
const Index i)
const
85 if (i == 0)
return m_v1;
86 if (i == 1)
return m_v2;
102 using iterator_category = std::input_iterator_tag;
104 using difference_type = std::ptrdiff_t;
117 bool operator!=(
const iterator& rhs)
const
119 return m_edge != rhs.m_edge || m_i != rhs.m_i;
126 Index operator*()
const {
return m_edge[m_i]; }
129 iterator end()
const {
return iterator(*
this, 2); }
132 bool has_shared_vertex(
const EdgeType<Index>& other)
const
134 return m_v1 == other.m_v1 || m_v1 == other.m_v2 || m_v2 == other.m_v1 || m_v2 == other.m_v2;
136 Index get_shared_vertex(
const EdgeType<Index>& other)
const
138 la_runtime_assert(*
this != other,
"get_shared_vertex() failed due to identical edges");
139 if (m_v1 == other.m_v1)
return m_v1;
140 if (m_v1 == other.m_v2)
return m_v1;
141 if (m_v2 == other.m_v1)
return m_v2;
142 if (m_v2 == other.m_v2)
return m_v2;
143 return invalid<Index>();
145 Index get_other_vertex(Index v)
const
148 if (m_v1 == v)
return m_v2;
153template <
typename Index,
typename T>
154using EdgeMap = std::unordered_map<EdgeType<Index>, T>;
156template <
typename Index>
157using EdgeSet = std::unordered_set<EdgeType<Index>>;
159template <
typename MeshType>
161 std::unordered_map<EdgeType<typename MeshType::Index>, std::vector<typename MeshType::Index>>;
165template <
typename MeshType>
166EdgeFacetMap<MeshType> compute_edge_facet_map_in_active_facets(
168 const std::unordered_set<typename MeshType::Index>& active_facets)
170 using Index =
typename MeshType::Index;
171 std::unordered_map<EdgeType<Index>, std::vector<Index>> edge_facet_map;
172 const Index num_facets = mesh.get_num_facets();
173 const Index vertex_per_facet = mesh.get_vertex_per_facet();
174 const typename MeshType::FacetArray& facets = mesh.get_facets();
175 edge_facet_map.reserve(active_facets.size() * vertex_per_facet);
176 for (Index i = 0; i < num_facets; ++i) {
177 if (active_facets.find(i) == active_facets.end())
continue;
178 for (Index j = 0; j < vertex_per_facet; ++j) {
179 const Index v1 = facets(i, j);
180 const Index v2 = facets(i, (j + 1) % vertex_per_facet);
181 const EdgeType<Index> edge(v1, v2);
182 auto it = edge_facet_map.find(edge);
183 if (it == edge_facet_map.end()) {
184 edge_facet_map[edge] = {i};
186 it->second.push_back(i);
190 return edge_facet_map;
195template <
typename MeshType>
196EdgeFacetMap<MeshType> compute_edge_facet_map_in_active_vertices(
198 const std::unordered_set<typename MeshType::Index>& active_vertices)
200 using Index =
typename MeshType::Index;
202 std::unordered_set<Index> active_facets;
204 if (mesh.is_connectivity_initialized()) {
206 for (Index v : active_vertices) {
207 for (Index f : mesh.get_facets_adjacent_to_vertex(v)) {
208 active_facets.insert(f);
212 const Index num_facets = mesh.get_num_facets();
213 const Index vertex_per_facet = mesh.get_vertex_per_facet();
214 const typename MeshType::FacetArray& facets = mesh.get_facets();
215 for (Index i = 0; i < num_facets; ++i) {
216 if (active_facets.find(i) != active_facets.end())
continue;
217 for (Index j = 0; j < vertex_per_facet; ++j) {
218 if (active_vertices.find(facets(i, j)) != active_vertices.end()) {
219 active_facets.insert(i);
225 return compute_edge_facet_map_in_active_facets(mesh, active_facets);
230template <
typename Index>
235 return lagrange::safe_cast<std::size_t>(key.v1() + key.v2());
#define la_runtime_assert(...)
Runtime assertion check.
Definition: assert.h:169
Main namespace for Lagrange.
Definition: AABBIGL.h:30