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
use fj_math::{Circle, Line, Point, Vector};
use crate::objects::{Curve, CurveKind, Cycle, Edge, Face};
pub fn reverse_face(face: &Face) -> Face {
if face.triangles().is_some() {
panic!("Reversing tri-rep faces is not supported");
}
let surface = face.surface().reverse();
let exteriors = reverse_local_coordinates_in_cycle(face.exteriors());
let interiors = reverse_local_coordinates_in_cycle(face.interiors());
Face::new(surface)
.with_exteriors(exteriors)
.with_interiors(interiors)
.with_color(face.color())
}
fn reverse_local_coordinates_in_cycle<'r>(
cycles: impl IntoIterator<Item = &'r Cycle> + 'r,
) -> impl Iterator<Item = Cycle> + 'r {
cycles.into_iter().map(|cycle| {
let surface = cycle.surface().reverse();
let edges = cycle.edges().map(|edge| {
let curve = {
let local = match edge.curve().kind() {
CurveKind::Circle(circle) => {
let center = Point::from([
circle.center().u,
-circle.center().v,
]);
let a = Vector::from([circle.a().u, -circle.a().v]);
let b = Vector::from([circle.b().u, -circle.b().v]);
CurveKind::Circle(Circle::new(center, a, b))
}
CurveKind::Line(line) => {
let origin =
Point::from([line.origin().u, -line.origin().v]);
let direction = Vector::from([
line.direction().u,
-line.direction().v,
]);
CurveKind::Line(Line::from_origin_and_direction(
origin, direction,
))
}
};
Curve::new(local, *edge.curve().global())
};
Edge::from_curve_and_vertices(curve, *edge.vertices())
});
Cycle::new(surface).with_edges(edges)
})
}
#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;
use crate::objects::{Face, Surface};
#[test]
fn reverse_face() {
let surface = Surface::xy_plane();
let original = Face::build(surface).polygon_from_points([
[0., 0.],
[1., 0.],
[0., 1.],
]);
let reversed = super::reverse_face(&original);
let surface = Surface::xy_plane().reverse();
let expected = Face::build(surface)
.polygon_from_points([[0., 0.], [1., 0.], [0., -1.]])
.into_face();
assert_eq!(expected, reversed);
}
}