Lagrange
remove_short_edges.h
1/*
2 * Copyright 2019 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 <limits>
16#include <memory>
17
18#include <lagrange/Mesh.h>
19#include <lagrange/MeshTrait.h>
20#include <lagrange/attributes/map_attributes.h>
21#include <lagrange/common.h>
22#include <lagrange/compute_edge_lengths.h>
23#include <lagrange/create_mesh.h>
24#include <lagrange/legacy/inline.h>
25#include <lagrange/mesh_cleanup/remove_isolated_vertices.h>
26#include <lagrange/mesh_cleanup/remove_topologically_degenerate_triangles.h>
27#include <lagrange/utils/DisjointSets.h>
28#include <lagrange/utils/safe_cast.h>
29
30namespace lagrange {
31LAGRANGE_LEGACY_INLINE
32namespace legacy {
33
44template <typename MeshType>
45std::unique_ptr<MeshType> remove_short_edges(
46 const MeshType& in_mesh,
47 typename MeshType::Scalar tol = 0.0)
48{
49 static_assert(MeshTrait<MeshType>::is_mesh(), "Input type is not Mesh");
50 using Index = typename MeshType::Index;
51
52 lagrange::logger().trace("[remove_short_edges]");
53
54 // Topological degeneracy can affect the index mapping algorithm used here.
55 // So eliminating topological degeneracy first.
56 auto meshPtr = remove_topologically_degenerate_triangles(in_mesh);
57 auto& mesh = *meshPtr;
58
59 const auto num_vertices = mesh.get_num_vertices();
60 const auto num_facets = mesh.get_num_facets();
61 const auto vertex_per_facet = mesh.get_vertex_per_facet();
62
63 DisjointSets<Index> clusters(num_vertices);
64
66 const auto num_edges = mesh.get_num_edges();
67 const auto& edge_lengths = mesh.get_edge_attribute("length");
68 for (Index edge_idx = 0; edge_idx < num_edges; ++edge_idx) {
69 const auto& edge = mesh.get_edge_vertices(edge_idx);
70 const auto& length = edge_lengths(edge_idx);
71 if (length <= tol) {
72 clusters.merge(edge[0], edge[1]);
73 }
74 }
75
76 auto facets = mesh.get_facets(); // Intentionally copying the data.
77 std::transform(
78 facets.data(),
79 facets.data() + num_facets * vertex_per_facet,
80 facets.data(),
81 [&](Index i) { return clusters.find(i); });
82 auto mesh2 = create_mesh(mesh.get_vertices(), std::move(facets));
83
84 // Above we create topologically degenerate triangles, but vertex and
85 // facet indexes don't actually change, so we map attributes directly
86 map_attributes(mesh, *mesh2);
87
88 mesh2 = remove_topologically_degenerate_triangles(*mesh2);
89 mesh2 = remove_isolated_vertices(*mesh2);
90 return mesh2;
91}
92
93} // namespace legacy
94} // namespace lagrange
Definition: Mesh.h:48
LA_CORE_API spdlog::logger & logger()
Retrieves the current logger.
Definition: Logger.cpp:40
AttributeId compute_edge_lengths(SurfaceMesh< Scalar, Index > &mesh, const EdgeLengthOptions &options={})
Computes edge lengths attribute.
Definition: compute_edge_lengths.cpp:28
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_isolated_vertices(SurfaceMesh< Scalar, Index > &mesh)
Removes isolated vertices of a mesh.
Definition: remove_isolated_vertices.cpp:20
void remove_short_edges(SurfaceMesh< Scalar, Index > &mesh, Scalar threshold=0)
Collapse all edges shorter than a given tolerance.
Definition: remove_short_edges.cpp:29