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
use std::fmt;
use fj_math::{Point, Scalar};
use crate::objects::{Curve, Vertex};
pub fn validate_curve(
curve: &Curve,
max_distance: impl Into<Scalar>,
) -> Result<(), CoherenceIssues> {
let max_distance = max_distance.into();
let points_curve = [-2., -1., 0., 1., 2.].map(|point| Point::from([point]));
for point_curve in points_curve {
let point_surface = curve.kind().point_from_curve_coords(point_curve);
let point_surface_as_global =
curve.surface().point_from_surface_coords(point_surface);
let point_global =
curve.global().kind().point_from_curve_coords(point_curve);
let distance = (point_surface_as_global - point_global).magnitude();
if distance > max_distance {
Err(CurveCoherenceMismatch {
point_curve,
point_surface,
point_surface_as_global,
point_global,
curve: *curve,
})?
}
}
Ok(())
}
pub fn validate_vertex(
vertex: &Vertex,
max_distance: impl Into<Scalar>,
) -> Result<(), CoherenceIssues> {
let max_distance = max_distance.into();
let local = vertex.position();
let local_as_global = vertex
.curve()
.global()
.kind()
.point_from_curve_coords(local);
let global = vertex.global().position();
let distance = (local_as_global - global).magnitude();
if distance > max_distance {
Err(VertexCoherenceMismatch {
local,
local_as_global,
global,
})?
}
Ok(())
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug, thiserror::Error)]
pub enum CoherenceIssues {
#[error("Mismatch between surface and global forms of curve")]
Curve(#[from] CurveCoherenceMismatch),
#[error("Mismatch between local and global coordinates of vertex")]
Vertex(#[from] VertexCoherenceMismatch),
}
#[derive(Debug, thiserror::Error)]
pub struct CurveCoherenceMismatch {
pub point_curve: Point<1>,
pub point_surface: Point<2>,
pub point_surface_as_global: Point<3>,
pub point_global: Point<3>,
pub curve: Curve,
}
impl fmt::Display for CurveCoherenceMismatch {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"local: {:?} (converted to surface: {:?}; to global: {:?}), global: {:?},",
self.point_curve, self.point_surface, self.point_surface_as_global, self.point_global,
)
}
}
#[derive(Debug, Default, thiserror::Error)]
pub struct VertexCoherenceMismatch {
pub local: Point<1>,
pub local_as_global: Point<3>,
pub global: Point<3>,
}
impl fmt::Display for VertexCoherenceMismatch {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"local: {:?} (converted to global: {:?}), global: {:?},",
self.local, self.local_as_global, self.global,
)
}
}