Lagrange
reorder_mesh_vertices.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 <cassert>
15
16#include <lagrange/Mesh.h>
17#include <lagrange/MeshTrait.h>
18#include <lagrange/attributes/map_attributes.h>
19#include <lagrange/common.h>
20#include <lagrange/create_mesh.h>
21#include <lagrange/legacy/inline.h>
22#include <lagrange/utils/safe_cast.h>
23
24namespace lagrange {
25LAGRANGE_LEGACY_INLINE
26namespace legacy {
27
50template <typename MeshType>
51std::unique_ptr<MeshType> reorder_mesh_vertices(
52 const MeshType& mesh,
53 const typename MeshType::IndexList& forward_mapping)
54{
55 static_assert(MeshTrait<MeshType>::is_mesh(), "Input type is not Mesh");
57 mesh.get_vertex_per_facet() == 3,
58 std::string("vertex per facet is ") + std::to_string(mesh.get_vertex_per_facet()));
59
60 using Index = typename MeshType::Index;
61 using VertexArray = typename MeshType::VertexArray;
62 using FacetArray = typename MeshType::FacetArray;
63 using IndexList = typename MeshType::IndexList;
64
65 const auto num_old_vertices = mesh.get_num_vertices();
66 const auto& vertices = mesh.get_vertices();
67 const auto& facets = mesh.get_facets();
68 la_runtime_assert(num_old_vertices == safe_cast<Index>(forward_mapping.size()));
69
70 auto forward_mapping_no_invalid = [&forward_mapping](const Index io) {
71 return forward_mapping[io] == invalid<Index>() ? io : forward_mapping[io];
72 };
73
74 // Cound the number of new vertices
75 Index num_new_vertices = 0;
76 for (const auto io : range(num_old_vertices)) {
77 num_new_vertices = std::max(num_new_vertices, forward_mapping_no_invalid(io));
78 }
79 num_new_vertices += 1; // num_of_*** = biggest index + 1
81 num_new_vertices <= num_old_vertices,
82 "Number of vertices should not increase");
83
84
85 // Create the backward mapping and the new vertices
86 IndexList backward_mapping(num_new_vertices, invalid<Index>());
87 VertexArray vertices_new(num_new_vertices, mesh.get_dim());
88 for (const auto io : range(num_old_vertices)) {
89 const auto in = forward_mapping_no_invalid(io);
90 backward_mapping[in] = io;
91 vertices_new.row(in) = vertices.row(io);
92 }
93 // The mapping should be surjective.
95 std::find(backward_mapping.begin(), backward_mapping.end(), invalid<Index>()) ==
96 backward_mapping.end(),
97 "Forward mapping is not surjective");
98
99 // Create new faces
100 FacetArray facets_new(facets.rows(), facets.cols());
101 for (auto i : range(facets.rows())) {
102 facets_new(i, 0) = forward_mapping_no_invalid(facets(i, 0));
103 facets_new(i, 1) = forward_mapping_no_invalid(facets(i, 1));
104 facets_new(i, 2) = forward_mapping_no_invalid(facets(i, 2));
105 }
106
107 // Create new mesh
108 auto mesh2 = create_mesh(std::move(vertices_new), std::move(facets_new));
109
110 // Port attributes
111 map_attributes(mesh, *mesh2, backward_mapping);
112
113 return mesh2;
114}
115
116} // namespace legacy
117} // namespace lagrange
Definition: Mesh.h:48
#define la_runtime_assert(...)
Runtime assertion check.
Definition: assert.h:169
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