-
-
Notifications
You must be signed in to change notification settings - Fork 119
/
Copy pathregion.rs
135 lines (119 loc) · 3.26 KB
/
region.rs
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 fj_interop::Color;
use fj_math::Vector;
use crate::{
geometry::SurfaceGeometry,
objects::{Cycle, Face, Region, Surface},
operations::{
insert::Insert, reverse::Reverse, transform::TransformObject,
},
storage::Handle,
Core,
};
use super::{SweepCache, SweepCycle};
/// # Sweep a [`Region`]
///
/// See [module documentation] for more information.
///
/// [module documentation]: super
pub trait SweepRegion {
/// # Sweep the [`Region`]
///
/// Sweep the region into multiple sets of faces. Each set of faces is
/// formed by sweeping one of the region's cycles, then adding a top face.
///
/// Requires the surface that the face that the region belongs to is defined
/// in.
///
/// There no "bottom" face. Whether having one is desirable depends on the
/// context of the caller of this operation, and falls outside of this
/// operation's scope.
fn sweep_region(
&self,
surface: &Handle<Surface>,
color: Option<Color>,
path: impl Into<Vector<3>>,
cache: &mut SweepCache,
core: &mut Core,
) -> SweptRegion;
}
impl SweepRegion for Region {
fn sweep_region(
&self,
surface: &Handle<Surface>,
color: Option<Color>,
path: impl Into<Vector<3>>,
cache: &mut SweepCache,
core: &mut Core,
) -> SweptRegion {
let path = path.into();
let mut faces = Vec::new();
let top_exterior = sweep_cycle(
self.exterior(),
&surface.geometry(),
color,
&mut faces,
path,
cache,
core,
);
let top_interiors = self
.interiors()
.iter()
.map(|bottom_cycle| {
sweep_cycle(
bottom_cycle,
&surface.geometry(),
color,
&mut faces,
path,
cache,
core,
)
})
.collect::<Vec<_>>();
let top_face = {
let top_surface = surface.translate(path, core).insert(core);
let top_region =
Region::new(top_exterior, top_interiors).insert(core);
Face::new(top_surface, top_region)
};
SweptRegion {
top_face,
side_faces: faces,
}
}
}
fn sweep_cycle(
bottom_cycle: &Cycle,
bottom_surface: &SurfaceGeometry,
color: Option<Color>,
faces: &mut Vec<Face>,
path: Vector<3>,
cache: &mut SweepCache,
core: &mut Core,
) -> Handle<Cycle> {
let swept_cycle = bottom_cycle.reverse(core).sweep_cycle(
bottom_surface,
color,
path,
cache,
core,
);
faces.extend(swept_cycle.faces);
swept_cycle.top_cycle.insert(core)
}
/// The result of sweeping a [`Region`]
///
/// See [`SweepRegion`].
pub struct SweptRegion {
/// The side faces created by the sweep
pub side_faces: Vec<Face>,
/// The top face created by the sweep
pub top_face: Face,
}
impl SweptRegion {
/// Return an iterator over all of the faces
pub fn all_faces(self) -> impl Iterator<Item = Face> {
self.side_faces.into_iter().chain([self.top_face])
}
}