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
//! Named per-vertex data carried alongside positions.
//!
//! A mesh often arrives with more per-vertex information than geometry:
//! material ids, texture coordinates, analysis results, source entity
//! handles. That data is not decoration -- losing it silently is how a
//! quantity takeoff ends up unable to say which wall a triangle came from.
//!
//! Two things make this hard, and both are modelled here rather than
//! wished away:
//!
//! - Not every value can be blended. Interpolating a material id at a new
//! vertex invents a material that was never authored, so a channel must
//! declare whether blending is even meaningful.
//! - Some operations genuinely cannot preserve a channel. A boolean cut
//! creates vertices with no preimage in either operand. Reporting that
//! honestly beats fabricating a plausible value.
use Scalar;
/// How a channel's values may be combined when a new vertex appears.
///
/// This is a property of the DATA, not of the operation. An operation asks
/// the channel what is permissible; it does not decide on the channel's
/// behalf.
/// Per-vertex values under a caller-chosen name.
///
/// `values.len()` must equal the mesh's vertex count. The invariant is
/// checked by [`crate::TriMesh::validate_structure`] rather than enforced
/// at construction, matching how this crate treats dirty imported data:
/// representable, then validated at a trust boundary.
/// What happened to a channel during an operation.
///
/// Reported rather than rejected, matching how `BooleanEvidence` treats a
/// no-op cut: the caller is told, and decides whether it matters.
/// Why a channel could not be carried through an operation.