Lagrange
compute_mesh_covariance.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 <Eigen/Core>
15
16#include <lagrange/Mesh.h>
17#include <lagrange/utils/range.h>
18
19namespace lagrange {
20LAGRANGE_LEGACY_INLINE
21namespace legacy {
22
23// Compute the covariance matrix
24// mesh_ref, reference to the mesh
25// center, the point around which the covariance is computed.
26// active_facets, the facets that are included in the covariance computation.
27// Empty would imply all facets.
28//
29// Adapted from https://github.com/mkazhdan/ShapeSPH/blob/master/Util/TriangleMesh.h#L101
30template <typename MeshType>
31Eigen::Matrix<typename MeshType::Scalar, 3, 3> compute_mesh_covariance( //
32 const MeshType& mesh_ref,
33 const typename MeshType::VertexType& center,
34 const typename MeshType::IndexList& active_facets = typename MeshType::IndexList())
35{ //
36
37 using Scalar = typename MeshType::Scalar;
38 using Vector3 = Eigen::Matrix<Scalar, 1, 3>;
39 using Matrix3 = Eigen::Matrix<Scalar, 3, 3>;
40
41 const auto& vertices = mesh_ref.get_vertices();
42 const auto& facets = mesh_ref.get_facets();
43
44 la_runtime_assert(vertices.cols() == 3, "Currently, only 3 dimensions are supported");
45 la_runtime_assert(facets.cols() == 3, "Currently, only triangles are supported");
46
47 Matrix3 factors;
48 factors.row(0) << Scalar(1. / 2), Scalar(1. / 3), Scalar(1. / 6);
49 factors.row(1) << Scalar(1. / 3), Scalar(1. / 4), Scalar(1. / 8);
50 factors.row(2) << Scalar(1. / 6), Scalar(1. / 8), Scalar(1. / 12);
51
52 auto triangle_covariance = [&factors](
53 const Vector3& v1,
54 const Vector3& v2,
55 const Vector3& v3,
56 const Vector3& c) -> Matrix3 {
57 const Scalar a = (v2 - v1).cross(v3 - v1).norm();
58 Matrix3 p;
59 p.row(0) = v1 - c;
60 p.row(1) = v3 - v1;
61 p.row(2) = v2 - v3;
62
63 const Matrix3 covariance = a * p.transpose() * factors * p;
64
65 return covariance;
66 };
67
68 Matrix3 covariance = Matrix3::Zero();
69 for (auto facet_id : range_sparse(mesh_ref.get_num_facets(), active_facets)) {
70 const Vector3 v0 = vertices.row(facets(facet_id, 0));
71 const Vector3 v1 = vertices.row(facets(facet_id, 1));
72 const Vector3 v2 = vertices.row(facets(facet_id, 2));
73 covariance += triangle_covariance(v0, v1, v2, center);
74 } // over triangles
75
76 // Return
77 return covariance;
78}
79
80
81} // namespace legacy
82} // namespace lagrange
Definition: Mesh.h:48
#define la_runtime_assert(...)
Runtime assertion check.
Definition: assert.h:169
internal::SparseRange< Index > range_sparse(Index max, const std::vector< Index > &active)
Returns an iterable object representing a subset of the range [0, max).
Definition: range.h:217
Main namespace for Lagrange.
Definition: AABBIGL.h:30
std::array< std::array< Scalar, 3 >, 3 > compute_mesh_covariance(const SurfaceMesh< Scalar, Index > &mesh, const MeshCovarianceOptions &options={})
Compute the covariance matrix w.r.t.
Definition: compute_mesh_covariance.cpp:28