Lagrange
compute_lift_operator.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 <Eigen/Sparse>
15
16namespace lagrange {
17
29template <typename MeshType, typename Cloud, typename Indices>
30auto compute_lift_operator_from_sampling(const MeshType& mesh , const Cloud& closest_points , const Indices& element_indices )
31{
32 using Scalar = typename MeshType::Scalar;
33 using Operator = Eigen::SparseMatrix<Scalar>;
34 using Index = typename Operator::StorageIndex;
35 using Triplet = Eigen::Triplet<Scalar, Index>;
36 using Triplets = std::vector<Triplet>;
37 using std::get;
38
39 const auto& vertices = mesh.get_vertices();
40 const auto& facets = mesh.get_facets();
41
42 assert(closest_points.rows() == element_indices.rows());
43
44 Triplets triplets;
45 for (Index kk = 0, kk_max = static_cast<Index>(closest_points.rows()); kk < kk_max; kk++) {
46 const auto element_index = element_indices(kk);
47
48 assert(element_index >= 0);
49 assert(element_index < facets.rows());
50 const auto facet = facets.row(element_index).template cast<Index>();
51
52 const auto p0 = vertices.row(facet(0));
53 const auto p1 = vertices.row(facet(1));
54 const auto p2 = vertices.row(facet(2));
55 const auto pp = closest_points.row(kk);
56
57 const auto f0 = p0 - pp;
58 const auto f1 = p1 - pp;
59 const auto f2 = p2 - pp;
60
61 const auto aa = (p1 - p0).cross(p2 - p0).norm();
62 const auto w0 = f1.cross(f2).norm() / aa;
63 const auto w1 = f2.cross(f0).norm() / aa;
64 const auto w2 = f0.cross(f1).norm() / aa;
65
66 assert(fabs(w0 + w1 + w2 - 1) < 1e-5);
67 assert((w0 * p0 + w1 * p1 + w2 * p2 - pp).array().abs().maxCoeff() < 1e-5);
68
69 triplets.emplace_back(Triplet{kk, facet(0), w0});
70 triplets.emplace_back(Triplet{kk, facet(1), w1});
71 triplets.emplace_back(Triplet{kk, facet(2), w2});
72 }
73
74 Operator ope(element_indices.size(), vertices.rows());
75 ope.setFromTriplets(std::cbegin(triplets), std::cend(triplets));
76
77 return ope;
78}
79
89template <typename MeshType, typename ClosestPoints>
91 const MeshType& mesh ,
92 const ClosestPoints&
93 projections )
94{
95 using Scalar = typename MeshType::Scalar;
96 using Operator = Eigen::SparseMatrix<Scalar>;
97 using Index = typename Operator::StorageIndex;
98 using Triplet = Eigen::Triplet<Scalar, Index>;
99 using Triplets = std::vector<Triplet>;
100
101 const auto& vertices = mesh.get_vertices();
102 const auto& facets = mesh.get_facets();
103
104 Triplets triplets;
105 Index out_index = 0;
106 for (const auto& projection : projections) {
107 assert(projection.embedding_element_idx >= 0);
108 assert(projection.embedding_element_idx < facets.rows());
109 const auto facet = facets.row(projection.embedding_element_idx).template cast<Index>();
110
111 const auto p0 = vertices.row(facet(0));
112 const auto p1 = vertices.row(facet(1));
113 const auto p2 = vertices.row(facet(2));
114
115 const auto f0 = p0 - projection.closest_point;
116 const auto f1 = p1 - projection.closest_point;
117 const auto f2 = p2 - projection.closest_point;
118
119 const auto aa = (p1 - p0).cross(p2 - p0).norm();
120 const auto w0 = f1.cross(f2).norm() / aa;
121 const auto w1 = f2.cross(f0).norm() / aa;
122 const auto w2 = f0.cross(f1).norm() / aa;
123
124 assert(fabs(w0 + w1 + w2 - 1) < 1e-5);
125 assert(
126 (w0 * p0 + w1 * p1 + w2 * p2 - projection.closest_point).array().abs().maxCoeff() <
127 1e-5);
128
129 triplets.emplace_back(Triplet{out_index, facet(0), w0});
130 triplets.emplace_back(Triplet{out_index, facet(1), w1});
131 triplets.emplace_back(Triplet{out_index, facet(2), w2});
132
133 out_index++;
134 }
135
136 Operator ope(projections.size(), vertices.rows());
137 ope.setFromTriplets(std::cbegin(triplets), std::cend(triplets));
138
139 return ope;
140}
141
142} // namespace lagrange
Definition: Mesh.h:48
Main namespace for Lagrange.
Definition: AABBIGL.h:30
auto compute_lift_operator_from_sampling(const MeshType &mesh, const Cloud &closest_points, const Indices &element_indices)
This compute the sparse bilinear map from mesh vertex attributes to point cloud attributes.
Definition: compute_lift_operator.h:30
auto compute_lift_operator_from_projections(const MeshType &mesh, const ClosestPoints &projections)
This compute the sparse bilinear map from mesh vertex attributes to point cloud attributes.
Definition: compute_lift_operator.h:90