Visual Computing Library  devel
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
30#include <vclib/space/complex.h>
31#include <vclib/space/core.h>
32
33namespace vcl {
34
42template<FaceMeshConcept MeshType>
43double volume(const MeshType& m)
44{
45 MeshInertia<MeshType> i(m);
46 return i.volume();
47}
48
56template<FaceMeshConcept MeshType>
57double surfaceArea(const MeshType& m)
58{
59 using FaceType = MeshType::FaceType;
60
61 double area = 0;
62 for (const FaceType& f : m.faces()) {
63 area += faceArea(f);
64 }
65 return area;
66}
67
79template<FaceMeshConcept MeshType>
80double borderLength(const MeshType& m)
81{
82 using FaceType = MeshType::FaceType;
83
85
86 double l = 0;
87 for (const FaceType& f : m.faces()) {
88 for (uint i = 0; i < f.vertexNumber(); ++i) {
89 if (f.adjFace(i) == nullptr) {
90 l += f.vertex(i)->position().dist(
91 f.vertexMod(i + 1)->position());
92 }
93 }
94 }
95 return l;
96}
97
108template<MeshConcept MeshType>
109auto covarianceMatrixOfPointCloud(const MeshType& m)
110{
111 using VertexType = MeshType::VertexType;
112 using PositionType = VertexType::PositionType;
113 using ScalarType = PositionType::ScalarType;
114
115 PositionType bar = barycenter(m);
116
117 Matrix33<ScalarType> mm;
118 mm.setZero();
119 // compute covariance matrix
120 for (const VertexType& v : m.vertices()) {
121 PositionType e = v.position() - bar;
122 mm += e.outerProduct(e);
123 }
124 return mm;
125}
126
135template<FaceMeshConcept MeshType>
136auto covarianceMatrixOfMesh(const MeshType& m)
137{
138 using VertexType = MeshType::VertexType;
139 using FaceType = MeshType::FaceType;
140 using PositionType = VertexType::PositionType;
141 using ScalarType = PositionType::ScalarType;
142
143 PositionType bar = shellBarycenter(m);
144 Matrix33<ScalarType> C;
145 C.setZero();
146 Matrix33<ScalarType> C0;
147 C0.setZero();
148 C0(0, 0) = C0(1, 1) = 2.0;
149 C0(0, 1) = C0(1, 0) = 1.0;
150 C0 *= 1 / 24.0;
151 // integral of (x,y,0) in the same triangle
152 Eigen::Vector3<ScalarType> x;
153 x << 1 / 6.0, 1 / 6.0, 0;
154 Matrix33<ScalarType> A; // matrix that bring the vertices to (v1-v0,v2-v0,n)
155 Matrix33<ScalarType> DC;
156
157 for (const FaceType& f : m.faces()) {
158 const PositionType& p0 = f.vertex(0)->position();
159 const PositionType& p1 = f.vertex(1)->position();
160 const PositionType& p2 = f.vertex(2)->position();
161 PositionType n = (p1 - p0).cross(p2 - p0);
162 double da = n.norm();
163 n /= da * da;
164
165 PositionType tmpp = p1 - p0;
166 for (uint j = 0; j < 3; j++)
167 A(j, 0) = tmpp(j);
168 tmpp = p2 - p0;
169 for (uint j = 0; j < 3; j++)
170 A(j, 1) = tmpp(j);
171 for (uint j = 0; j < 3; j++)
172 A(j, 2) = n(j);
173 Eigen::Vector3<ScalarType> delta;
174 tmpp = p0 - bar;
175 for (uint j = 0; j < 3; j++)
176 delta(j) = tmpp(j);
177
178 /* DC is calculated as integral of (A*x+delta) * (A*x+delta)^T over the
179 * triangle, where delta = v0-bary */
180 DC.setZero();
181 DC += A * C0 * A.transpose();
182 Matrix33<ScalarType> tmp = (A * x) * delta.transpose();
183 DC += tmp + tmp.transpose();
184 DC += tmp;
185 tmp = delta * delta.transpose();
186 DC += tmp * 0.5;
187 DC *= da; // the determinant of A is also the double area of f
188 C += DC;
189 }
190 return C;
191}
192
207template<typename ScalarType, MeshConcept MeshType>
208std::vector<ScalarType> vertexRadiusFromWeights(
209 const MeshType& m,
210 Range auto&& weights,
211 double diskRadius,
212 double radiusVariance,
213 bool invert = false)
214{
215 using VertexType = MeshType::VertexType;
216
217 assert(std::ranges::size(weights) == m.vertexNumber());
218
219 std::vector<ScalarType> radius(m.vertexContainerSize());
220 const auto [min, max] = std::ranges::minmax_element(weights);
221
222 double minRad = diskRadius;
223 double maxRad = diskRadius * radiusVariance;
224 double deltaQ = *max - *min;
225 double deltaRad = maxRad - minRad;
226 for (const auto& [v, w] : std::views::zip(m.vertices(), weights)) {
227 double num = invert ? (*max - w) : (w - *min);
228 radius[m.index(v)] = minRad + deltaRad * (num / deltaQ);
229 }
230
231 return radius;
232}
233
249template<FaceMeshConcept MeshType>
250std::vector<std::pair<uint, uint>> creaseFaceEdges(
251 const MeshType& m,
252 double angleRadNeg,
253 double angleRadPos,
254 bool alsoBorderEdges = false)
255{
257
258 std::vector<std::pair<uint, uint>> creaseEdges;
259
260 for (const auto& f : m.faces()) {
261 for (uint i = 0; i < f.vertexNumber(); ++i) {
262 if (f.adjFace(i) == nullptr) {
263 // border edge
264 if (alsoBorderEdges) {
265 creaseEdges.push_back({f.index(), i});
266 }
267 }
268 else {
269 // internal edge
270 double angle = faceDihedralAngleOnEdge(f, i);
271 if (angle < angleRadNeg || angle > angleRadPos) {
272 creaseEdges.push_back({f.index(), i});
273 }
274 }
275 }
276 }
277 return creaseEdges;
278}
279
280} // namespace vcl
281
282#endif // VCL_ALGORITHMS_MESH_STAT_GEOMETRY_H
constexpr auto max(const T &p1, const T &p2)
Returns the maximum between the two parameters.
Definition min_max.h:81
constexpr auto min(const T &p1, const T &p2)
Returns the minimum between the two parameters.
Definition min_max.h:40
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:108
void requirePerFaceAdjacentFaces(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a AdjacentFaces Component,...
Definition face_requirements.h:960
constexpr detail::FacesView faces
A view that allows to iterate overt the Face elements of an object.
Definition face.h:84
constexpr detail::VerticesView vertices
A view that allows to iterate over the Vertex elements of an object.
Definition vertex.h:92