Coverage Report

Created: 2026-08-31 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PROJ/src/projections/polyhedral/polyhedra/validation.h
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Project:  PROJ
4
 * Purpose:  Compile-time validation helper for polyhedron seed meshes.
5
 * Author:   Felix Palmer
6
 *
7
 ****************************************************************************/
8
9
#ifndef POLYHEDRA_VALIDATION_H
10
#define POLYHEDRA_VALIDATION_H
11
12
#include "../conway.h"
13
14
namespace polyhedra {
15
16
template <int NV, int NF, int NFV>
17
constexpr bool
18
0
all_vertices_on_unit_sphere(const polyhedral::Mesh<NV, NF, NFV> &m) {
19
0
    constexpr double tol = 1e-12;
20
0
    for (int i = 0; i < NV; i++) {
21
0
        const auto &v = m.vertices[i];
22
0
        const double err = v.x * v.x + v.y * v.y + v.z * v.z - 1.0;
23
0
        if (err < -tol || err > tol)
24
0
            return false;
25
0
    }
26
0
    return true;
27
0
}
Unexecuted instantiation: bool polyhedra::all_vertices_on_unit_sphere<20, 12, 5>(polyhedral::Mesh<20, 12, 5> const&)
Unexecuted instantiation: bool polyhedra::all_vertices_on_unit_sphere<12, 20, 3>(polyhedral::Mesh<12, 20, 3> const&)
Unexecuted instantiation: bool polyhedra::all_vertices_on_unit_sphere<4, 4, 3>(polyhedral::Mesh<4, 4, 3> const&)
28
29
template <int NV, int NF, int NFV>
30
constexpr bool
31
0
face_indices_well_formed(const polyhedral::Mesh<NV, NF, NFV> &m) {
32
0
    for (int f = 0; f < NF; f++) {
33
0
        for (int k = 0; k < NFV; k++) {
34
0
            if (m.faces[f][k] < 0 || m.faces[f][k] >= NV)
35
0
                return false;
36
0
            for (int j = k + 1; j < NFV; j++) {
37
0
                if (m.faces[f][k] == m.faces[f][j])
38
0
                    return false;
39
0
            }
40
0
        }
41
0
    }
42
0
    return true;
43
0
}
Unexecuted instantiation: bool polyhedra::face_indices_well_formed<20, 12, 5>(polyhedral::Mesh<20, 12, 5> const&)
Unexecuted instantiation: bool polyhedra::face_indices_well_formed<12, 20, 3>(polyhedral::Mesh<12, 20, 3> const&)
Unexecuted instantiation: bool polyhedra::face_indices_well_formed<4, 4, 3>(polyhedral::Mesh<4, 4, 3> const&)
44
45
// Two topological conditions:
46
// V - E + F = 2 for any closed convex polyhedron,
47
// E = NF * NFV / 2 (each edge shared by exactly two NFV-gon faces).
48
template <int NV, int NF, int NFV>
49
0
constexpr bool euler_holds(const polyhedral::Mesh<NV, NF, NFV> &) {
50
0
    return (NF * NFV) % 2 == 0 && NV - (NF * NFV) / 2 + NF == 2;
51
0
}
Unexecuted instantiation: bool polyhedra::euler_holds<20, 12, 5>(polyhedral::Mesh<20, 12, 5> const&)
Unexecuted instantiation: bool polyhedra::euler_holds<12, 20, 3>(polyhedral::Mesh<12, 20, 3> const&)
Unexecuted instantiation: bool polyhedra::euler_holds<4, 4, 3>(polyhedral::Mesh<4, 4, 3> const&)
52
53
template <auto &M> struct validate_polyhedron {
54
    static_assert(M.vertices[0].x == 0.0 && M.vertices[0].y == 0.0 &&
55
                      M.vertices[0].z == 1.0,
56
                  "V0 must be at (0, 0, 1)");
57
    static_assert(all_vertices_on_unit_sphere(M),
58
                  "all vertices must lie on the unit sphere");
59
    static_assert(face_indices_well_formed(M),
60
                  "face vertex indices must be in [0, NV) "
61
                  "and unique within each face");
62
    static_assert(euler_holds(M),
63
                  "polyhedron must satisfy Euler's formula V - E + F = 2");
64
};
65
66
} // namespace polyhedra
67
68
#endif // POLYHEDRA_VALIDATION_H