Visual Computing Library
Loading...
Searching...
No Matches
geometry.h
1/*****************************************************************************
2 * VCLib *
3 * Visual Computing Library *
4 * *
5 * Copyright(C) 2021-2025 *
6 * Visual Computing Lab *
7 * ISTI - Italian National Research Council *
8 * *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the Mozilla Public License Version 2.0 as published *
13 * by the Mozilla Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * Mozilla Public License Version 2.0 *
20 * (https://www.mozilla.org/en-US/MPL/2.0/) for more details. *
21 ****************************************************************************/
22
23#ifndef VCL_ALGORITHMS_MESH_STAT_GEOMETRY_H
24#define VCL_ALGORITHMS_MESH_STAT_GEOMETRY_H
25
26#include "barycenter.h"
27
28#include <vclib/algorithms/mesh/face_topology.h>
29#include <vclib/space/complex/mesh_inertia.h>
30#include <vclib/space/core/matrix.h>
31
32namespace vcl {
33
41template<FaceMeshConcept MeshType>
42double volume(const MeshType& m)
43{
44 MeshInertia<MeshType> i(m);
45 return i.volume();
46}
47
55template<FaceMeshConcept MeshType>
56double surfaceArea(const MeshType& m)
57{
58 using FaceType = MeshType::FaceType;
59
60 double area = 0;
61 for (const FaceType& f : m.faces()) {
62 area += faceArea(f);
63 }
64 return area;
65}
66
74template<FaceMeshConcept MeshType>
75double borderLength(const MeshType& m)
76{
77 using FaceType = MeshType::FaceType;
78
79 double l = 0;
80 for (const FaceType& f : m.faces()) {
81 for (uint i = 0; i < f.vertexNumber(); ++i) {
82 if (f.adjFace(i) == nullptr) {
83 l += f.vertex(i)->coord().dist(f.vertexMod(i + 1)->coord());
84 }
85 }
86 }
87 return l;
88}
89
100template<MeshConcept MeshType>
101auto covarianceMatrixOfPointCloud(const MeshType& m)
102{
103 using VertexType = MeshType::VertexType;
104 using ScalarType = VertexType::CoordType::ScalarType;
105
106 auto bar = barycenter(m);
107
108 Matrix33<ScalarType> mm;
109 mm.setZero();
110 // compute covariance matrix
111 for (const VertexType& v : m.vertices()) {
112 auto e = v.coord() - bar;
113 m += e.outerProduct(e);
114 }
115 return m;
116}
117
126template<FaceMeshConcept MeshType>
127auto covarianceMatrixOfMesh(const MeshType& m)
128{
129 using VertexType = MeshType::VertexType;
130 using FaceType = MeshType::FaceType;
131 using CoordType = VertexType::CoordType;
132 using ScalarType = CoordType::ScalarType;
133
134 CoordType bar = shellBarycenter(m);
135 Matrix33<ScalarType> C;
136 C.setZero();
137 Matrix33<ScalarType> C0;
138 C0.setZero();
139 C0(0, 0) = C0(1, 1) = 2.0;
140 C0(0, 1) = C0(1, 0) = 1.0;
141 C0 *= 1 / 24.0;
142 // integral of (x,y,0) in the same triangle
143 Eigen::Vector3<ScalarType> x;
144 x << 1 / 6.0, 1 / 6.0, 0;
145 Matrix33<ScalarType> A; // matrix that bring the vertices to (v1-v0,v2-v0,n)
146 Matrix33<ScalarType> DC;
147
148 for (const FaceType& f : m.faces()) {
149 const CoordType& p0 = f.vertex(0)->coord();
150 const CoordType& p1 = f.vertex(1)->coord();
151 const CoordType& p2 = f.vertex(2)->coord();
152 CoordType n = (p1 - p0).cross(p2 - p0);
153 double da = n.norm();
154 n /= da * da;
155
156 CoordType tmpp = p1 - p0;
157 for (uint j = 0; j < 3; j++)
158 A(j, 0) = tmpp(j);
159 tmpp = p2 - p0;
160 for (uint j = 0; j < 3; j++)
161 A(j, 1) = tmpp(j);
162 for (uint j = 0; j < 3; j++)
163 A(j, 2) = n(j);
164 Eigen::Vector3<ScalarType> delta;
165 tmpp = p0 - bar;
166 for (uint j = 0; j < 3; j++)
167 delta(j) = tmpp(j);
168
169 /* DC is calculated as integral of (A*x+delta) * (A*x+delta)^T over the
170 * triangle, where delta = v0-bary */
171 DC.setZero();
172 DC += A * C0 * A.transpose();
173 Matrix33<ScalarType> tmp = (A * x) * delta.transpose();
174 DC += tmp + tmp.transpose();
175 DC += tmp;
176 tmp = delta * delta.transpose();
177 DC += tmp * 0.5;
178 DC *= da; // the determinant of A is also the double area of f
179 C += DC;
180 }
181 return C;
182}
183
198template<MeshConcept MeshType, typename ScalarType>
199std::vector<ScalarType> vertexRadiusFromWeights(
200 const MeshType& m,
201 const std::vector<ScalarType>& weights,
202 double diskRadius,
203 double radiusVariance,
204 bool invert = false)
205{
206 using VertexType = MeshType::VertexType;
207
208 std::vector<ScalarType> radius(m.vertexContainerSize());
209 auto minmax = std::minmax_element(weights.begin(), weights.end());
210
211 float minRad = diskRadius;
212 float maxRad = diskRadius * radiusVariance;
213 float deltaQ = *minmax.second - *minmax.first;
214 float deltaRad = maxRad - minRad;
215 for (const VertexType& v : m.vertices()) {
216 ScalarType w = weights[m.index(v)];
217 radius[m.index(v)] =
218 minRad +
219 deltaRad *
220 ((invert ? *minmax.second - w : w - *minmax.first) / deltaQ);
221 }
222
223 return radius;
224}
225
241template<FaceMeshConcept MeshType>
242std::vector<std::pair<uint, uint>> creaseFaceEdges(
243 const MeshType& m,
244 double angleRadNeg,
245 double angleRadPos,
246 bool alsoBorderEdges = false)
247{
249
250 std::vector<std::pair<uint, uint>> creaseEdges;
251
252 for (const auto& f : m.faces()) {
253 for (uint i = 0; i < f.vertexNumber(); ++i) {
254 if (f.adjFace(i) == nullptr) {
255 // border edge
256 if (alsoBorderEdges) {
257 creaseEdges.push_back({f.index(), i});
258 }
259 }
260 else {
261 // internal edge
262 double angle = faceDihedralAngleOnEdge(f, i);
263 if (angle < angleRadNeg || angle > angleRadPos) {
264 creaseEdges.push_back({f.index(), i});
265 }
266 }
267 }
268 }
269 return creaseEdges;
270}
271
272} // namespace vcl
273
274#endif // VCL_ALGORITHMS_MESH_STAT_GEOMETRY_H
auto faceArea(const FaceType &f)
Computes the area of a face. Works both for triangle and polygonal faces, and it is optimized in case...
Definition geometry.h:101
void requirePerFaceAdjacentFaces(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a AdjacentFaces Component,...
Definition face_requirements.h:698
constexpr detail::FacesView faces
A view that allows to iterate overt the Face elements of an object.
Definition face.h:52
constexpr detail::VerticesView vertices
A view that allows to iterate over the Vertex elements of an object.
Definition vertex.h:60