16#include <tbb/parallel_for.h>
17#include <tbb/parallel_sort.h>
19#include <lagrange/Logger.h>
20#include <lagrange/Mesh.h>
21#include <lagrange/common.h>
22#include <lagrange/create_mesh.h>
23#include <lagrange/legacy/inline.h>
33template <
typename MeshType>
34auto unify_corner_indices(
36 const std::vector<std::string>& indexed_attribute_names,
37 std::vector<typename MeshType::Index>& corner_to_unified_index) ->
typename MeshType::Index
39 using AttributeArray =
typename MeshType::AttributeArray;
40 using Index =
typename MeshType::Index;
41 using IndexArray =
typename MeshType::IndexArray;
43 const Index num_attrs = safe_cast<Index>(indexed_attribute_names.size());
44 std::vector<std::tuple<const AttributeArray&, const IndexArray&>> attrs;
45 attrs.reserve(num_attrs);
46 for (
const auto& attr_name : indexed_attribute_names) {
47 attrs.emplace_back(mesh.get_indexed_attribute(attr_name));
50 const Index num_vertices = mesh.get_num_vertices();
51 const Index num_facets = mesh.get_num_facets();
52 const Index vertex_per_facet = mesh.get_vertex_per_facet();
53 const auto& facets = mesh.get_facets();
54 const Index num_corners = num_facets * vertex_per_facet;
55 std::vector<Index> corner_indices(num_corners);
56 std::iota(corner_indices.begin(), corner_indices.end(), 0);
59 auto corner_index_comp = [&](Index i, Index j) ->
bool {
60 const Index fi = i / vertex_per_facet;
61 const Index ci = i % vertex_per_facet;
62 const Index fj = j / vertex_per_facet;
63 const Index cj = j % vertex_per_facet;
65 if (facets(fi, ci) == facets(fj, cj)) {
66 for (
auto k :
range(num_attrs)) {
67 const auto& indices = std::get<1>(attrs[k]);
68 if (indices(fi, ci) != indices(fj, cj)) {
69 return indices(fi, ci) < indices(fj, cj);
73 return facets(fi, ci) < facets(fj, cj);
78 auto corner_index_eq = [&](Index i, Index j) ->
bool {
79 const Index fi = i / vertex_per_facet;
80 const Index ci = i % vertex_per_facet;
81 const Index fj = j / vertex_per_facet;
82 const Index cj = j % vertex_per_facet;
84 if (facets(fi, ci) == facets(fj, cj)) {
85 for (
auto k :
range(num_attrs)) {
86 const auto& indices = std::get<1>(attrs[k]);
87 if (indices(fi, ci) != indices(fj, cj)) {
97 tbb::parallel_sort(corner_indices.begin(), corner_indices.end(), corner_index_comp);
99 std::vector<bool> visited(num_vertices,
false);
100 Index num_unified_vertices = num_vertices;
101 corner_to_unified_index.resize(num_corners);
103 for (Index i = 0; i < num_corners;) {
104 const Index fi = corner_indices[i] / vertex_per_facet;
105 const Index ci = corner_indices[i] % vertex_per_facet;
107 Index vi = facets(fi, ci);
111 vi = num_unified_vertices++;
115 while (j < num_corners && corner_index_eq(corner_indices[i], corner_indices[j])) {
116 corner_to_unified_index[corner_indices[j]] = vi;
122 return num_unified_vertices;
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