1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//! Structured mesh validation failures.
use core::fmt;
/// Cheap structural validation failure.
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MeshValidationError {
/// Triangle index buffer is not divisible by three.
IncompleteTriangle { index_count: usize },
/// Position index does not exist.
PositionIndexOutOfRange { index: u32, position_count: usize },
/// Non-indexed normals do not align with positions.
NormalCount { expected: usize, actual: usize },
/// Independently indexed normals do not align with corners.
NormalIndexCount { expected: usize, actual: usize },
/// Normal index does not exist.
NormalIndexOutOfRange { index: u32, normal_count: usize },
/// A channel does not carry one tuple per vertex.
AttributeCount {
/// Channel name.
name: String,
/// Vertices in the mesh.
expected: usize,
/// Vertices the channel covers.
actual: usize,
},
/// A channel declares a zero tuple width, which covers no vertices.
AttributeZeroWidth {
/// Channel name.
name: String,
},
/// Two channels share a name, so a lookup would be ambiguous.
AttributeDuplicateName {
/// The repeated name.
name: String,
},
/// A corner-indexed channel's `values` is not whole tuples.
AttributeRaggedValues {
/// Channel name.
name: String,
/// Scalars found.
values: usize,
/// Declared tuple width.
width: usize,
},
/// A corner-indexed channel does not have one entry per triangle corner.
AttributeCornerCount {
/// Channel name.
name: String,
/// Triangle corners in the mesh.
expected: usize,
/// Corner entries in the channel.
actual: usize,
},
/// A corner index points past the channel's values.
AttributeCornerIndexOutOfRange {
/// Channel name.
name: String,
/// The offending index.
index: u32,
/// Tuples available.
value_count: usize,
},
/// A triangle has some corners mapped and some unmapped.
AttributePartiallyMapped {
/// Channel name.
name: String,
/// The triangle.
triangle: usize,
},
}
impl fmt::Display for MeshValidationError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::IncompleteTriangle { index_count } => {
write!(f, "index count {index_count} is not divisible by three")
}
Self::PositionIndexOutOfRange {
index,
position_count,
} => write!(
f,
"position index {index} exceeds {position_count} positions"
),
Self::NormalCount { expected, actual } => {
write!(f, "expected {expected} normals, found {actual}")
}
Self::NormalIndexCount { expected, actual } => {
write!(f, "expected {expected} normal indices, found {actual}")
}
Self::NormalIndexOutOfRange {
index,
normal_count,
} => write!(f, "normal index {index} exceeds {normal_count} normals"),
Self::AttributeCount {
name,
expected,
actual,
} => write!(
f,
"attribute channel {name} covers {actual} vertices, mesh has {expected}"
),
Self::AttributeZeroWidth { name } => {
write!(f, "attribute channel {name} declares a zero tuple width")
}
Self::AttributeDuplicateName { name } => {
write!(f, "attribute channel name {name} is used more than once")
}
Self::AttributeRaggedValues {
name,
values,
width,
} => write!(
f,
"attribute channel {name} has {values} scalars, not a multiple of width {width}"
),
Self::AttributeCornerCount {
name,
expected,
actual,
} => write!(
f,
"attribute channel {name} has {actual} corner indices, mesh has {expected} corners"
),
Self::AttributeCornerIndexOutOfRange {
name,
index,
value_count,
} => write!(
f,
"attribute channel {name} corner index {index} exceeds {value_count} values"
),
Self::AttributePartiallyMapped { name, triangle } => write!(
f,
"attribute channel {name} maps only some corners of triangle {triangle}"
),
}
}
}
impl std::error::Error for MeshValidationError {}