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_STAT_QUALITY_H
24#define VCL_ALGORITHMS_MESH_STAT_QUALITY_H
25
26#include <vclib/math/base.h>
27#include <vclib/math/histogram.h>
28#include <vclib/mesh/requirements.h>
29#include <vclib/views/mesh.h>
30
31namespace vcl {
32
46template<MeshConcept MeshType>
47auto vertexQualityMinMax(const MeshType& m)
48{
49 requirePerVertexQuality(m);
50
51 auto [min, max] = std::ranges::minmax(m.vertices() | views::quality);
52 return std::make_pair(min, max);
53}
54
68template<FaceMeshConcept MeshType>
69auto faceQualityMinMax(const MeshType& m)
70{
72
73 auto [min, max] = std::ranges::minmax(m.faces() | views::quality);
74
75 return std::make_pair(min, max);
76}
77
89template<MeshConcept MeshType>
90auto vertexQualityAverage(const MeshType& m)
91{
92 requirePerVertexQuality(m);
93
94 using VertexType = MeshType::VertexType;
95 using QualityType = VertexType::QualityType;
96
97 QualityType avg = 0;
98
99 for (const VertexType& v : m.vertices())
100 avg += v.quality();
101
102 return avg / m.vertexNumber();
103}
104
116template<FaceMeshConcept MeshType>
117auto faceQualityAverage(const MeshType& m)
118{
120
121 using FaceType = MeshType::FaceType;
122 using QualityType = FaceType::QualityType;
123
124 QualityType avg = 0;
125
126 for (const FaceType& f : m.faces())
127 avg += f.quality();
128
129 return avg / m.faceNumber();
130}
131
145template<MeshConcept MeshType>
146std::vector<typename MeshType::VertexType::QualityType> vertexRadiusFromQuality(
147 const MeshType& m,
148 double diskRadius,
149 double radiusVariance,
150 bool invert = false)
151{
152 requirePerVertexQuality(m);
153
154 using VertexType = MeshType::VertexType;
155 using QualityType = VertexType::QualityType;
156
157 std::vector<QualityType> radius(m.vertexContainerSize());
158 std::pair<QualityType, QualityType> minmax = vertexQualityMinMax(m);
159
160 float minRad = diskRadius;
161 float maxRad = diskRadius * radiusVariance;
162 float deltaQ = minmax.second - minmax.first;
163 float deltaRad = maxRad - minRad;
164 for (const VertexType& v : m.vertices()) {
165 radius[m.index(v)] =
166 minRad + deltaRad * ((invert ? minmax.second - v.quality() :
167 v.quality() - minmax.first) /
168 deltaQ);
169 }
170
171 return radius;
172}
173
174template<MeshConcept MeshType, typename HScalar = double>
175Histogram<HScalar> vertexQualityHistogram(
176 const MeshType& m,
177 bool selectionOnly = false,
178 uint histSize = 10000)
179{
180 requirePerVertexQuality(m);
181
182 using VertexType = MeshType::VertexType;
183
184 auto minmax = vertexQualityMinMax(m);
185
186 Histogram<HScalar> h(minmax.first, minmax.second, histSize);
187 for (const VertexType& v : m.vertices()) {
188 if (!selectionOnly || v.selected()) {
189 assert(!isDegenerate(v.quality()));
190 h.addValue(v.quality());
191 }
192 }
193 return h;
194}
195
196template<FaceMeshConcept MeshType, typename HScalar = double>
197Histogram<HScalar> faceQualityHistogram(
198 const MeshType& m,
199 bool selectionOnly = false,
200 uint histSize = 10000)
201{
203
204 using FaceType = MeshType::FaceType;
205
206 auto minmax = vertexQualityMinMax(m);
207
208 Histogram<HScalar> h(minmax.first, minmax.second, histSize);
209 for (const FaceType& f : m.faces()) {
210 if (!selectionOnly || f.selected()) {
211 assert(!isDegenerate(f.quality()));
212 h.addValue(f.quality());
213 }
214 }
215 return h;
216}
217
218} // namespace vcl
219
220#endif // VCL_ALGORITHMS_MESH_STAT_QUALITY_H
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 auto max(const T &p1, const T &p2)
Returns the maximum between the two parameters.
Definition min_max.h:83
bool isDegenerate(Scalar number)
Checks if a floating point number is degenerate.
Definition base.h:45
constexpr auto min(const T &p1, const T &p2)
Returns the minimum between the two parameters.
Definition min_max.h:42
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