Skip to content

Commit c3a3c4c

Browse files
0HyperCubeKeavon
andauthored
Allow the Fill and Stroke nodes to work on groups (#2046)
* Add the apply style trait for generalised application of styles * Fix Clippy warn * Use existing trait * Remove unnecessary lifetimes --------- Co-authored-by: Keavon Chambers <[email protected]>
1 parent 9f7b393 commit c3a3c4c

File tree

1 file changed

+82
-24
lines changed

1 file changed

+82
-24
lines changed

node-graph/gcore/src/vector/vector_nodes.rs

Lines changed: 82 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,27 @@ use bezier_rs::{Cap, Join, Subpath, SubpathTValue, TValue};
1111
use glam::{DAffine2, DVec2};
1212
use rand::{Rng, SeedableRng};
1313

14+
/// Implemented for types that can be converted to an iterator of vector data.
15+
/// Used for the fill and stroke node so they can be used on VectorData or GraphicGroup
1416
trait VectorIterMut {
15-
fn vector_iter_mut(&mut self) -> impl ExactSizeIterator<Item = &mut VectorData>;
17+
fn vector_iter_mut(&mut self) -> impl Iterator<Item = (&mut VectorData, DAffine2)>;
1618
}
1719

1820
impl VectorIterMut for GraphicGroup {
19-
fn vector_iter_mut(&mut self) -> impl ExactSizeIterator<Item = &mut VectorData> {
20-
self.iter_mut().filter_map(|(element, _)| element.as_vector_data_mut()).collect::<Vec<_>>().into_iter()
21+
fn vector_iter_mut(&mut self) -> impl Iterator<Item = (&mut VectorData, DAffine2)> {
22+
let parent_transform = self.transform;
23+
// Grab only the direct children (perhaps unintuitive?)
24+
self.iter_mut().filter_map(|(element, _)| element.as_vector_data_mut()).map(move |vector| {
25+
let transform = parent_transform * vector.transform;
26+
(vector, transform)
27+
})
2128
}
2229
}
2330

2431
impl VectorIterMut for VectorData {
25-
fn vector_iter_mut(&mut self) -> impl ExactSizeIterator<Item = &mut VectorData> {
26-
std::iter::once(self)
32+
fn vector_iter_mut(&mut self) -> impl Iterator<Item = (&mut VectorData, DAffine2)> {
33+
let transform = self.transform;
34+
std::iter::once((self, transform))
2735
}
2836
}
2937

@@ -51,13 +59,12 @@ async fn assign_colors<F: 'n + Send, T: VectorIterMut>(
5159
repeat_every: u32,
5260
) -> T {
5361
let mut input = vector_group.eval(footprint).await;
54-
let vector_data = input.vector_iter_mut();
55-
let length = vector_data.len();
62+
let length = input.vector_iter_mut().count();
5663
let gradient = if reverse { gradient.reversed() } else { gradient };
5764

5865
let mut rng = rand::rngs::StdRng::seed_from_u64(seed.into());
5966

60-
for (i, vector_data) in vector_data.enumerate() {
67+
for (i, (vector_data, _)) in input.vector_iter_mut().enumerate() {
6168
let factor = match randomize {
6269
true => rng.gen::<f64>(),
6370
false => match repeat_every {
@@ -82,12 +89,23 @@ async fn assign_colors<F: 'n + Send, T: VectorIterMut>(
8289
}
8390

8491
#[node_macro::node(category("Vector: Style"), path(graphene_core::vector))]
85-
async fn fill<F: 'n + Send, T: Into<Fill> + 'n + Send>(
92+
async fn fill<F: 'n + Send, FillTy: Into<Fill> + 'n + Send, TargetTy: VectorIterMut + 'n + Send>(
8693
#[implementations(
8794
(),
8895
(),
8996
(),
9097
(),
98+
(),
99+
(),
100+
(),
101+
(),
102+
Footprint,
103+
Footprint,
104+
Footprint,
105+
Footprint,
106+
Footprint,
107+
Footprint,
108+
Footprint,
91109
Footprint,
92110
)]
93111
footprint: F,
@@ -96,9 +114,20 @@ async fn fill<F: 'n + Send, T: Into<Fill> + 'n + Send>(
96114
() -> VectorData,
97115
() -> VectorData,
98116
() -> VectorData,
117+
() -> GraphicGroup,
118+
() -> GraphicGroup,
119+
() -> GraphicGroup,
120+
() -> GraphicGroup,
121+
Footprint -> VectorData,
122+
Footprint -> VectorData,
123+
Footprint -> VectorData,
99124
Footprint -> VectorData,
125+
Footprint -> GraphicGroup,
126+
Footprint -> GraphicGroup,
127+
Footprint -> GraphicGroup,
128+
Footprint -> GraphicGroup,
100129
)]
101-
vector_data: impl Node<F, Output = VectorData>,
130+
vector_data: impl Node<F, Output = TargetTy>,
102131
#[implementations(
103132
Fill,
104133
Option<Color>,
@@ -108,59 +137,88 @@ async fn fill<F: 'n + Send, T: Into<Fill> + 'n + Send>(
108137
Option<Color>,
109138
Color,
110139
Gradient,
140+
Fill,
141+
Option<Color>,
142+
Color,
143+
Gradient,
144+
Fill,
145+
Option<Color>,
146+
Color,
147+
Gradient,
111148
)]
112149
#[default(Color::BLACK)]
113-
fill: T,
150+
fill: FillTy,
114151
_backup_color: Option<Color>,
115152
_backup_gradient: Gradient,
116-
) -> VectorData {
117-
let mut vector_data = vector_data.eval(footprint).await;
118-
vector_data.style.set_fill(fill.into());
153+
) -> TargetTy {
154+
let mut target = vector_data.eval(footprint).await;
155+
let fill: Fill = fill.into();
156+
for (target, _transform) in target.vector_iter_mut() {
157+
target.style.set_fill(fill.clone());
158+
}
119159

120-
vector_data
160+
target
121161
}
122162

123163
#[node_macro::node(category("Vector: Style"), path(graphene_core::vector))]
124-
async fn stroke<F: 'n + Send, T: Into<Option<Color>> + 'n + Send>(
164+
async fn stroke<F: 'n + Send, ColourTy: Into<Option<Color>> + 'n + Send, TargetTy: VectorIterMut + 'n + Send>(
125165
#[implementations(
126166
(),
127167
(),
168+
(),
169+
(),
170+
Footprint,
171+
Footprint,
172+
Footprint,
128173
Footprint,
129174
)]
130175
footprint: F,
131176
#[implementations(
132177
() -> VectorData,
133178
() -> VectorData,
179+
() -> GraphicGroup,
180+
() -> GraphicGroup,
134181
Footprint -> VectorData,
182+
Footprint -> VectorData,
183+
Footprint -> GraphicGroup,
184+
Footprint -> GraphicGroup,
135185
)]
136-
vector_data: impl Node<F, Output = VectorData>,
186+
vector_data: impl Node<F, Output = TargetTy>,
137187
#[implementations(
138188
Option<Color>,
139189
Color,
140190
Option<Color>,
141191
Color,
192+
Option<Color>,
193+
Color,
194+
Option<Color>,
195+
Color,
142196
)]
143197
#[default(Color::BLACK)]
144-
color: T,
198+
color: ColourTy,
145199
#[default(2.)] weight: f64,
146200
dash_lengths: Vec<f64>,
147201
dash_offset: f64,
148202
line_cap: crate::vector::style::LineCap,
149203
line_join: LineJoin,
150204
#[default(4.)] miter_limit: f64,
151-
) -> VectorData {
152-
let mut vector_data = vector_data.eval(footprint).await;
153-
vector_data.style.set_stroke(Stroke {
205+
) -> TargetTy {
206+
let mut target = vector_data.eval(footprint).await;
207+
let stroke = Stroke {
154208
color: color.into(),
155209
weight,
156210
dash_lengths,
157211
dash_offset,
158212
line_cap,
159213
line_join,
160214
line_join_miter_limit: miter_limit,
161-
transform: vector_data.transform,
162-
});
163-
vector_data
215+
transform: DAffine2::IDENTITY,
216+
};
217+
for (target, transform) in target.vector_iter_mut() {
218+
target.style.set_stroke(Stroke { transform, ..stroke.clone() });
219+
}
220+
221+
target
164222
}
165223

166224
#[node_macro::node(category("Vector"), path(graphene_core::vector))]

0 commit comments

Comments
 (0)