14#include <lagrange/MeshTrait.h>
15#include <lagrange/attributes/map_attributes.h>
16#include <lagrange/common.h>
17#include <lagrange/create_mesh.h>
18#include <lagrange/legacy/inline.h>
23#include <unordered_map>
43template <
typename MeshType>
46 static_assert(MeshTrait<MeshType>::is_mesh(),
"Input type is not Mesh");
47 using Index =
typename MeshType::FacetArray::Scalar;
48 using Facet = std::array<Index, 3>;
50 const Index num_facets = mesh.get_num_facets();
51 const auto& facets = mesh.get_facets();
53 auto facet_hash = [](
const Facet& f) {
return f[0] + f[1] + f[2]; };
54 auto facet_eq = [](
const Facet& f1,
const Facet& f2) {
55 return f1[0] == f2[0] && f1[1] == f2[1] && f1[2] == f2[2];
58 std::unordered_map<Facet, std::list<Index>,
decltype(facet_hash),
decltype(facet_eq)> facet_map(
62 for (Index i = 0; i < num_facets; i++) {
63 Facet f{facets(i, 0), facets(i, 1), facets(i, 2)};
64 std::sort(f.begin(), f.end());
65 auto itr = facet_map.find(f);
66 if (itr == facet_map.end()) {
67 facet_map.insert({f, {i}});
69 itr->second.push_back(i);
73 const auto num_unique_facets = facet_map.size();
74 typename MeshType::FacetArray unique_facets(num_unique_facets, 3);
75 std::vector<Index> ori_facet_indices(num_unique_facets);
77 for (
const auto& entry : facet_map) {
78 const auto& fs = entry.second;
79 assert(fs.size() > 0);
80 auto fid = fs.front();
84 Index inverted_fid = fid;
85 for (
const auto fj : fs) {
86 if ((facets(fj, 0) == facets(fid, 0) && facets(fj, 1) == facets(fid, 1) &&
87 facets(fj, 2) == facets(fid, 2)) ||
88 (facets(fj, 0) == facets(fid, 1) && facets(fj, 1) == facets(fid, 2) &&
89 facets(fj, 2) == facets(fid, 0)) ||
90 (facets(fj, 0) == facets(fid, 2) && facets(fj, 1) == facets(fid, 0) &&
91 facets(fj, 2) == facets(fid, 1))) {
98 if (orientation < 0) {
102 unique_facets.row(count) = facets.row(fid);
103 ori_facet_indices[count] = fid;
107 const auto vertices = mesh.get_vertices();
108 auto out_mesh =
create_mesh(std::move(vertices), std::move(unique_facets));
@ Facet
Per-facet mesh attributes.
Definition: AttributeFwd.h:31
void map_attributes(const SurfaceMesh< Scalar, Index > &source_mesh, SurfaceMesh< Scalar, Index > &target_mesh, span< const Index > mapping_data, span< const Index > mapping_offsets={}, const MapAttributesOptions &options={})
Map attributes from the source mesh to the target mesh.
Definition: map_attributes.cpp:26
Main namespace for Lagrange.
Definition: AABBIGL.h:30
auto create_mesh(const Eigen::MatrixBase< DerivedV > &vertices, const Eigen::MatrixBase< DerivedF > &facets)
This function create a new mesh given the vertex and facet arrays by copying data into the Mesh objec...
Definition: create_mesh.h:39
void remove_duplicate_facets(SurfaceMesh< Scalar, Index > &mesh, const RemoveDuplicateFacetOptions &opts={})
Remove duplicate facets in the mesh.
Definition: remove_duplicate_facets.cpp:235