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
use std::array;
use fj_interop::ext::ArrayExt;
use fj_math::Point;
use crate::{
objects::{GlobalEdge, GlobalVertex, HalfEdge, Objects, SurfaceVertex},
partial::{FullToPartialCache, MaybeCurve, Partial, PartialObject},
services::Service,
};
#[derive(Clone, Debug)]
pub struct PartialHalfEdge {
pub curve: Option<MaybeCurve>,
pub vertices: [(Option<Point<1>>, Partial<SurfaceVertex>); 2],
pub global_form: Partial<GlobalEdge>,
}
impl PartialObject for PartialHalfEdge {
type Full = HalfEdge;
fn from_full(
half_edge: &Self::Full,
cache: &mut FullToPartialCache,
) -> Self {
Self {
curve: Some(half_edge.curve().into()),
vertices: half_edge
.boundary()
.zip_ext(half_edge.surface_vertices())
.map(|(position, surface_vertex)| {
(
Some(position),
Partial::from_full(surface_vertex.clone(), cache),
)
}),
global_form: Partial::from_full(
half_edge.global_form().clone(),
cache,
),
}
}
fn build(self, objects: &mut Service<Objects>) -> Self::Full {
let curve = match self.curve.expect("Need path to build curve") {
MaybeCurve::Defined(path) => path,
undefined => {
panic!(
"Trying to build curve with undefined path: {undefined:?}"
)
}
};
let vertices = self.vertices.map(|vertex| {
let position_curve = vertex
.0
.expect("Can't build `HalfEdge` without boundary positions");
let surface_form = vertex.1.build(objects);
(position_curve, surface_form)
});
let global_form = self.global_form.build(objects);
HalfEdge::new(curve, vertices, global_form)
}
}
impl Default for PartialHalfEdge {
fn default() -> Self {
let curve = None;
let vertices = array::from_fn(|_| {
let surface_form = Partial::default();
(None, surface_form)
});
let global_vertices = vertices.each_ref_ext().map(
|vertex: &(Option<Point<1>>, Partial<SurfaceVertex>)| {
let surface_vertex = vertex.1.clone();
let global_vertex = surface_vertex.read().global_form.clone();
global_vertex
},
);
let global_form = Partial::from_partial(PartialGlobalEdge {
vertices: global_vertices,
});
Self {
curve,
vertices,
global_form,
}
}
}
#[derive(Clone, Debug, Default)]
pub struct PartialGlobalEdge {
pub vertices: [Partial<GlobalVertex>; 2],
}
impl PartialObject for PartialGlobalEdge {
type Full = GlobalEdge;
fn from_full(
global_edge: &Self::Full,
cache: &mut FullToPartialCache,
) -> Self {
Self {
vertices: global_edge
.vertices()
.access_in_normalized_order()
.map(|vertex| Partial::from_full(vertex, cache)),
}
}
fn build(self, objects: &mut Service<Objects>) -> Self::Full {
let vertices = self.vertices.map(|vertex| vertex.build(objects));
GlobalEdge::new(vertices)
}
}