Lagrange
All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Modules Pages
zip_boundary.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 <numeric>
15#include <unordered_map>
16#include <unordered_set>
17
18#include <lagrange/Mesh.h>
19#include <lagrange/attributes/map_attributes.h>
20#include <lagrange/bvh/create_BVH.h>
21#include <lagrange/common.h>
22#include <lagrange/mesh_cleanup/remove_isolated_vertices.h>
23#include <lagrange/utils/range.h>
24
25namespace lagrange {
26namespace bvh {
27
31template <typename MeshType>
32std::unique_ptr<MeshType> zip_boundary(MeshType& mesh, typename MeshType::Scalar radius)
33{
34 using Index = typename MeshType::Index;
35
36 auto get_boundary_vertices = [&mesh]() {
37 mesh.initialize_edge_data();
38
39 std::vector<Index> boundary_vertices;
40 boundary_vertices.reserve(mesh.get_num_vertices());
41 for (auto v : range(mesh.get_num_vertices())) {
42 if (mesh.is_boundary_vertex(v)) {
43 boundary_vertices.push_back(v);
44 }
45 }
46 return boundary_vertices;
47 };
48
49 auto get_boundary_points = [&mesh](const auto& boundary_vertices) {
50 typename MeshType::VertexArray points(boundary_vertices.size(), mesh.get_dim());
51 for (Index i = 0; i < (Index)boundary_vertices.size(); ++i) {
52 const auto v = boundary_vertices[i];
53 points.row(i) = mesh.get_vertices().row(v);
54 }
55 return points;
56 };
57
58 auto compute_boundary_vertex_mapping =
59 [&radius](const auto& engine, const auto& boundary_vertices, const auto& boundary_points) {
60 std::unordered_map<Index, Index> vertex_mapping;
61 for (Index bvi = 0; bvi < (Index)boundary_vertices.size(); ++bvi) {
62 const Index vi = boundary_vertices[bvi];
63 if (vertex_mapping.find(vi) != vertex_mapping.end()) continue;
64
65 auto nearby_vertices =
66 engine->query_in_sphere_neighbours(boundary_points.row(bvi), radius);
67 for (const auto& entry : nearby_vertices) {
68 const Index bvj = entry.closest_vertex_idx;
69 const Index vj = boundary_vertices[bvj];
70
71 vertex_mapping[vj] = vi;
72 }
73 }
74
75 return vertex_mapping;
76 };
77
78 auto remap_vertices = [&mesh](const auto vertex_mapping) {
79 auto facets = mesh.get_facets();
80 std::transform(
81 facets.data(),
82 facets.data() + facets.size(),
83 facets.data(),
84 [&vertex_mapping](Index vi) {
85 const auto itr = vertex_mapping.find(vi);
86 if (itr == vertex_mapping.end()) {
87 return vi;
88 } else {
89 return itr->second;
90 }
91 });
92 auto out_mesh = lagrange::create_mesh(mesh.get_vertices(), facets);
93
94 BackwardMeshMapping<MeshType> mapping;
95 mapping.vertex.resize(out_mesh->get_num_vertices());
96 std::iota(mapping.vertex.begin(), mapping.vertex.end(), 0);
97 for (const auto& entry : vertex_mapping) {
98 mapping.vertex[entry.first] = entry.second;
99 }
100 map_attributes(mesh, *out_mesh, mapping);
101 return out_mesh;
102 };
103
104 const auto boundary_vertices = get_boundary_vertices();
105 const auto boundary_points = get_boundary_points(boundary_vertices);
106 auto engine = lagrange::bvh::create_BVH(lagrange::bvh::BVHType::NANOFLANN, boundary_points);
107 const auto vertex_mapping =
108 compute_boundary_vertex_mapping(engine, boundary_vertices, boundary_points);
109 const auto out_mesh = remap_vertices(vertex_mapping);
110 return remove_isolated_vertices(*out_mesh);
111}
112
113} // namespace bvh
114} // namespace lagrange
Definition: Mesh.h:48
Index get_num_vertices() const
Retrieves the number of vertices.
Definition: SurfaceMesh.h:671
void remap_vertices(SurfaceMesh< Scalar, Index > &mesh, span< const Index > forward_mapping, RemapVerticesOptions options={})
Remap vertices of a mesh based on provided forward mapping.
Definition: remap_vertices.cpp:136
internal::Range< Index > range(Index end)
Returns an iterable object representing the range [0, end).
Definition: range.h:176
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