Lagrange
midpoint_subdivision.h
1/*
2 * Copyright 2020 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 <lagrange/Mesh.h>
15#include <lagrange/MeshTrait.h>
16#include <lagrange/create_mesh.h>
17#include <lagrange/legacy/inline.h>
18
19namespace lagrange {
20namespace subdivision {
21LAGRANGE_LEGACY_INLINE
22namespace legacy {
23
35template <
36 typename MeshType,
37 std::enable_if_t<lagrange::MeshTraitHelper::is_mesh<MeshType>::value>* = nullptr>
38std::unique_ptr<MeshType> midpoint_subdivision(MeshType& mesh)
39{
40 static_assert(MeshTrait<MeshType>::is_mesh(), "Input type is not Mesh");
41 la_runtime_assert(mesh.get_vertex_per_facet() == 3, "Only triangle meshes are supported");
42
43 using Scalar = typename MeshType::Scalar;
44 using Index = typename MeshType::Index;
45 using VertexArray = typename MeshType::VertexArray;
46 using FacetArray = typename MeshType::FacetArray;
47
48 mesh.initialize_edge_data();
49 const auto nv = mesh.get_num_vertices();
50 const auto ne = mesh.get_num_edges();
51 const auto nf = mesh.get_num_facets();
52
53 VertexArray V(nv + ne, mesh.get_dim());
54 FacetArray F(nf * 4, 3);
55 V.topRows(nv) = mesh.get_vertices();
56 for (Index e = 0; e < ne; ++e) {
57 auto v = mesh.get_edge_vertices(e);
58 V.row(nv + e) =
59 Scalar(0.5) * (mesh.get_vertices().row(v[0]) + mesh.get_vertices().row(v[1]));
60 }
61 for (Index f = 0; f < mesh.get_num_facets(); ++f) {
62 const Index v0 = mesh.get_facets()(f, 0);
63 const Index v1 = mesh.get_facets()(f, 1);
64 const Index v2 = mesh.get_facets()(f, 2);
65 const Index e0 = nv + mesh.get_edge(f, 0);
66 const Index e1 = nv + mesh.get_edge(f, 1);
67 const Index e2 = nv + mesh.get_edge(f, 2);
68 F.row(4 * f + 0) << v0, e0, e2;
69 F.row(4 * f + 1) << v1, e1, e0;
70 F.row(4 * f + 2) << v2, e2, e1;
71 F.row(4 * f + 3) << e0, e1, e2;
72 }
73
74 return lagrange::create_mesh(V, F);
75}
76
77} // namespace legacy
78} // namespace subdivision
79} // namespace lagrange
Definition: Mesh.h:48
#define la_runtime_assert(...)
Runtime assertion check.
Definition: assert.h:169
SurfaceMesh< Scalar, Index > midpoint_subdivision(const SurfaceMesh< Scalar, Index > &mesh)
Performs one step of midpoint subdivision for triangle meshes.
Definition: midpoint_subdivision.cpp:22
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