Visual Computing Library  devel
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/mesh/stat.h>
27
28#include <vclib/algorithms/core.h>
29#include <vclib/mesh.h>
30
31namespace vcl {
32
40template<uint ELEM_ID, MeshConcept MeshType, typename QualityType>
41void setPerElementQuality(MeshType& mesh, QualityType quality)
42{
43 requirePerElementComponent<ELEM_ID, CompId::QUALITY>(mesh);
44
45 std::ranges::fill(
46 mesh.template elements<ELEM_ID>() | vcl::views::quality, quality);
47}
48
57template<uint ELEM_ID, MeshConcept MeshType, typename QualityType>
58void clampPerElementQuality(MeshType& mesh, QualityType minQ, QualityType maxQ)
59{
60 requirePerElementComponent<ELEM_ID, CompId::QUALITY>(mesh);
61
62 for (auto&& q : mesh.template elements<ELEM_ID>() | vcl::views::quality) {
63 q = std::clamp(q, minQ, maxQ);
64 }
65}
66
75template<uint ELEM_ID, MeshConcept MeshType, typename QualityType>
76void normalizePerElementQuality(
77 MeshType& mesh,
78 QualityType minQ = 0,
79 QualityType maxQ = 1)
80{
81 requirePerElementComponent<ELEM_ID, CompId::QUALITY>(mesh);
82
83 QualityType range = maxQ - minQ;
84 auto [eMinQ, eMaxQ] = elementQualityMinMax<ELEM_ID>(mesh);
85
86 for (auto&& q : mesh.template elements<ELEM_ID>() | vcl::views::quality) {
87 q = minQ + range * ((q - eMinQ) / (eMaxQ - eMinQ));
88 }
89}
90
97template<MeshConcept MeshType, typename QualityType>
98void setPerVertexQuality(MeshType& mesh, QualityType quality)
99{
100 setPerElementQuality<ElemId::VERTEX>(mesh, quality);
101}
102
109template<FaceMeshConcept MeshType, typename QualityType>
110void setPerFaceQuality(MeshType& mesh, QualityType quality)
111{
112 setPerElementQuality<ElemId::FACE>(mesh, quality);
113}
114
122template<MeshConcept MeshType, typename QualityType>
123void clampPerVertexQuality(MeshType& mesh, QualityType minQ, QualityType maxQ)
124{
125 clampPerElementQuality<ElemId::VERTEX>(mesh, minQ, maxQ);
126}
127
135template<FaceMeshConcept MeshType, typename QualityType>
136void clampPerFaceQuality(MeshType& mesh, QualityType minQ, QualityType maxQ)
137{
138 clampPerElementQuality<ElemId::FACE>(mesh, minQ, maxQ);
139}
140
149template<MeshConcept MeshType, typename QualityType>
150void normalizePerVertexQuality(
151 MeshType& mesh,
152 QualityType minQ = 0,
153 QualityType maxQ = 1)
154{
155 normalizePerElementQuality<ElemId::VERTEX>(mesh, minQ, maxQ);
156}
157
166template<FaceMeshConcept MeshType, typename QualityType>
167void normalizePerFaceQuality(
168 MeshType& mesh,
169 QualityType minQ = 0,
170 QualityType maxQ = 1)
171{
172 normalizePerElementQuality<ElemId::FACE>(mesh, minQ, maxQ);
173}
174
187template<FaceMeshConcept MeshType>
188void setPerVertexQualityFromVertexValence(MeshType& m)
189{
190 requirePerVertexQuality(m);
191
192 using VertexType = MeshType::VertexType;
193 using FaceType = MeshType::FaceType;
194
195 setPerVertexQuality(m, 0);
196
197 for (FaceType& f : m.faces()) {
198 for (VertexType* v : f.vertices()) {
199 v->quality() += 1;
200 }
201 }
202}
203
214template<FaceMeshConcept MeshType>
215void setPerFaceQualityFromFaceArea(MeshType& m)
216{
218
219 using FaceType = MeshType::FaceType;
220
221 for (FaceType& f : m.faces()) {
222 f.quality() = faceArea(f);
223 }
224}
225
226template<MeshConcept MeshType>
227void setPerVertexQualityFromPrincipalCurvatureGaussian(MeshType& m)
228{
229 requirePerVertexQuality(m);
230 requirePerVertexPrincipalCurvature(m);
231
232 using VertexType = MeshType::VertexType;
233
234 for (VertexType& v : m.vertices()) {
235 v.quality() = v.principalCurvature().maxValue() *
236 v.principalCurvature().minValue();
237 }
238}
239
240template<MeshConcept MeshType>
241void setPerVertexQualityFromPrincipalCurvatureMean(MeshType& m)
242{
243 requirePerVertexQuality(m);
244 requirePerVertexPrincipalCurvature(m);
245
246 using VertexType = MeshType::VertexType;
247
248 for (VertexType& v : m.vertices()) {
249 v.quality() = (v.principalCurvature().maxValue() +
250 v.principalCurvature().minValue()) /
251 2;
252 }
253}
254
255template<MeshConcept MeshType>
256void setPerVertexQualityFromPrincipalCurvatureMinValue(MeshType& m)
257{
258 requirePerVertexQuality(m);
259 requirePerVertexPrincipalCurvature(m);
260
261 using VertexType = MeshType::VertexType;
262
263 for (VertexType& v : m.vertices()) {
264 v.quality() = v.principalCurvature().minValue();
265 }
266}
267
268template<MeshConcept MeshType>
269void setPerVertexQualityFromPrincipalCurvatureMaxValue(MeshType& m)
270{
271 requirePerVertexQuality(m);
272 requirePerVertexPrincipalCurvature(m);
273
274 using VertexType = MeshType::VertexType;
275
276 for (VertexType& v : m.vertices()) {
277 v.quality() = v.principalCurvature().maxValue();
278 }
279}
280
292template<MeshConcept MeshType>
293void setPerVertexQualityFromPrincipalCurvatureShapeIndex(MeshType& m)
294{
295 requirePerVertexQuality(m);
296 requirePerVertexPrincipalCurvature(m);
297
298 using VertexType = MeshType::VertexType;
299 using ScalarType = VertexType::PrincipalCurvatureType::ScalarType;
300
301 for (VertexType& v : m.vertices()) {
302 ScalarType k1 = v.principalCurvature().maxValue();
303 ScalarType k2 = v.principalCurvature().minValue();
304 if (k1 < k2)
305 std::swap(k1, k2);
306 v.quality() = (2.0 / M_PI) * std::atan2(k1 + k2, k1 - k2);
307 }
308}
309
321template<MeshConcept MeshType>
322void setPerVertexQualityFromPrincipalCurvatureCurvedness(MeshType& m)
323{
324 requirePerVertexQuality(m);
325 requirePerVertexPrincipalCurvature(m);
326
327 using VertexType = MeshType::VertexType;
328 using ScalarType = VertexType::PrincipalCurvatureType::ScalarType;
329
330 for (VertexType& v : m.vertices()) {
331 ScalarType k1 = v.principalCurvature().maxValue();
332 ScalarType k2 = v.principalCurvature().minValue();
333
334 v.quality() = std::sqrt((k1 * k1 + k2 * k2) / 2.0);
335 }
336}
337
338} // namespace vcl
339
340#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:108
void requirePerFaceQuality(const MeshType &m)
This function asserts that a Mesh has a FaceContainer, the Face has a Quality Component,...
Definition face_requirements.h:1250
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