Visual Computing Library
Loading...
Searching...
No Matches
quality.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_UPDATE_QUALITY_H
24#define VCL_ALGORITHMS_MESH_UPDATE_QUALITY_H
25
26#include <vclib/algorithms/core/polygon.h>
27#include <vclib/algorithms/mesh/stat.h>
28#include <vclib/mesh/requirements.h>
29
30namespace vcl {
31
43template<MeshConcept MeshType>
44void setPerVertexQuality(
45 MeshType& m,
46 typename MeshType::VertexType::QualityType s)
47{
48 requirePerVertexQuality(m);
49
50 using VertexType = MeshType::VertexType;
51
52 for (VertexType& v : m.vertices()) {
53 v.quality() = s;
54 }
55}
56
68template<FaceMeshConcept MeshType>
69void setPerFaceQuality(MeshType& m, typename MeshType::FaceType::QualityType s)
70{
72
73 using FaceType = MeshType::FaceType;
74
75 for (FaceType& f : m.faces()) {
76 f.quality() = s;
77 }
78}
79
92template<MeshConcept MeshType>
93void clampPerVertexQuality(
94 MeshType& m,
95 typename MeshType::VertexType::QualityType minS,
96 typename MeshType::VertexType::QualityType maxS)
97{
98 requirePerVertexQuality(m);
99
100 using VertexType = MeshType::VertexType;
101
102 for (VertexType& v : m.vertices()) {
103 v.quality() = std::min(maxS, std::max(minS, v.quality()));
104 }
105}
106
119template<FaceMeshConcept MeshType>
120void clampPerFaceQuality(
121 MeshType& m,
122 typename MeshType::FaceType::QualityType minS,
123 typename MeshType::FaceType::QualityType maxS)
124{
126
127 using FaceType = MeshType::FaceType;
128
129 for (FaceType& f : m.faces()) {
130 f.quality() = std::min(maxS, std::max(minS, f.quality()));
131 }
132}
133
147template<MeshConcept MeshType>
148void normalizePerVertexQuality(
149 MeshType& m,
150 typename MeshType::VertexType::QualityType minS = 0,
151 typename MeshType::VertexType::QualityType maxS = 1)
152{
153 requirePerVertexQuality(m);
154
155 using VertexType = MeshType::VertexType;
156 using QualityType = VertexType::QualityType;
157
158 QualityType range = maxS - minS;
159 std::pair<QualityType, QualityType> p = vertexQualityMinMax(m);
160
161 for (VertexType& v : m.vertices()) {
162 v.quality() =
163 minS + range * ((v.quality() - p.first) / (p.second - p.first));
164 }
165}
166
180template<FaceMeshConcept MeshType>
181void normalizePerFaceQuality(
182 MeshType& m,
183 typename MeshType::FaceType::QualityType minS = 0,
184 typename MeshType::FaceType::QualityType maxS = 1)
185{
187
188 using FaceType = MeshType::FaceType;
189 using QualityType = FaceType::QualityType;
190
191 QualityType range = maxS - minS;
192 std::pair<QualityType, QualityType> p = faceQualityMinMax(m);
193
194 for (FaceType& f : m.faces()) {
195 f.quality() =
196 minS + range * ((f.quality() - p.first) / (p.second - p.first));
197 }
198}
199
212template<FaceMeshConcept MeshType>
213void setPerVertexQualityFromVertexValence(MeshType& m)
214{
215 requirePerVertexQuality(m);
216
217 using VertexType = MeshType::VertexType;
218 using FaceType = MeshType::FaceType;
219
220 setPerVertexQuality(m, 0);
221
222 for (FaceType& f : m.faces()) {
223 for (VertexType* v : f.vertices()) {
224 v->quality() += 1;
225 }
226 }
227}
228
239template<FaceMeshConcept MeshType>
240void setPerFaceQualityFromFaceArea(MeshType& m)
241{
243
244 using FaceType = MeshType::FaceType;
245
246 for (FaceType& f : m.faces()) {
247 f.quality() = faceArea(f);
248 }
249}
250
251template<MeshConcept MeshType>
252void setPerVertexQualityFromPrincipalCurvatureGaussian(MeshType& m)
253{
254 requirePerVertexQuality(m);
255 requirePerVertexPrincipalCurvature(m);
256
257 using VertexType = MeshType::VertexType;
258
259 for (VertexType& v : m.vertices()) {
260 v.quality() = v.principalCurvature().maxValue() *
261 v.principalCurvature().minValue();
262 }
263}
264
265template<MeshConcept MeshType>
266void setPerVertexQualityFromPrincipalCurvatureMean(MeshType& m)
267{
268 requirePerVertexQuality(m);
269 requirePerVertexPrincipalCurvature(m);
270
271 using VertexType = MeshType::VertexType;
272
273 for (VertexType& v : m.vertices()) {
274 v.quality() = (v.principalCurvature().maxValue() +
275 v.principalCurvature().minValue()) /
276 2;
277 }
278}
279
280template<MeshConcept MeshType>
281void setPerVertexQualityFromPrincipalCurvatureMinValue(MeshType& m)
282{
283 requirePerVertexQuality(m);
284 requirePerVertexPrincipalCurvature(m);
285
286 using VertexType = MeshType::VertexType;
287
288 for (VertexType& v : m.vertices()) {
289 v.quality() = v.principalCurvature().minValue();
290 }
291}
292
293template<MeshConcept MeshType>
294void setPerVertexQualityFromPrincipalCurvatureMaxValue(MeshType& m)
295{
296 requirePerVertexQuality(m);
297 requirePerVertexPrincipalCurvature(m);
298
299 using VertexType = MeshType::VertexType;
300
301 for (VertexType& v : m.vertices()) {
302 v.quality() = v.principalCurvature().maxValue();
303 }
304}
305
317template<MeshConcept MeshType>
318void setPerVertexQualityFromPrincipalCurvatureShapeIndex(MeshType& m)
319{
320 requirePerVertexQuality(m);
321 requirePerVertexPrincipalCurvature(m);
322
323 using VertexType = MeshType::VertexType;
324 using ScalarType = VertexType::PrincipalCurvatureType::ScalarType;
325
326 for (VertexType& v : m.vertices()) {
327 ScalarType k1 = v.principalCurvature().maxValue();
328 ScalarType k2 = v.principalCurvature().minValue();
329 if (k1 < k2)
330 std::swap(k1, k2);
331 v.quality() = (2.0 / M_PI) * std::atan2(k1 + k2, k1 - k2);
332 }
333}
334
346template<MeshConcept MeshType>
347void setPerVertexQualityFromPrincipalCurvatureCurvedness(MeshType& m)
348{
349 requirePerVertexQuality(m);
350 requirePerVertexPrincipalCurvature(m);
351
352 using VertexType = MeshType::VertexType;
353 using ScalarType = VertexType::PrincipalCurvatureType::ScalarType;
354
355 for (VertexType& v : m.vertices()) {
356 ScalarType k1 = v.principalCurvature().maxValue();
357 ScalarType k2 = v.principalCurvature().minValue();
358
359 v.quality() = std::sqrt((k1 * k1 + k2 * k2) / 2.0);
360 }
361}
362
363} // namespace vcl
364
365#endif // VCL_ALGORITHMS_MESH_UPDATE_QUALITY_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 requirePerFaceQuality(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a Quality Component,...
Definition face_requirements.h:875
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