Skip to content

Commit 112efe8

Browse files
committed
Add multi-level loop indexing with the 'Instance Repeat' node
1 parent be83783 commit 112efe8

File tree

3 files changed

+33
-17
lines changed

3 files changed

+33
-17
lines changed

editor/src/messages/portfolio/document_migration.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,19 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
969969
}
970970
}
971971

972+
// Add the "Depth" parameter to the "Instance Index" node
973+
if reference == "Instance Index" && inputs_count == 0 {
974+
let mut node_template = resolve_document_node_type(reference)?.default_node_template();
975+
document.network_interface.replace_implementation(node_id, network_path, &mut node_template);
976+
977+
document.network_interface.add_import(TaggedValue::None, false, 0, "Primary", "", &[*node_id]);
978+
document.network_interface.add_import(TaggedValue::U32(0), false, 1, "Loop Level", "TODO", &[*node_id]);
979+
}
980+
981+
// ==================================
982+
// PUT ALL MIGRATIONS ABOVE THIS LINE
983+
// ==================================
984+
972985
// Ensure layers are positioned as stacks if they are upstream siblings of another layer
973986
document.network_interface.load_structure();
974987
let all_layers = LayerNodeIdentifier::ROOT_PARENT.descendants(document.network_interface.document_metadata()).collect::<Vec<_>>();

node-graph/gcore/src/context.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub trait ExtractAnimationTime {
2727
}
2828

2929
pub trait ExtractIndex {
30-
fn try_index(&self) -> Option<usize>;
30+
fn try_index(&self) -> Option<Vec<usize>>;
3131
}
3232

3333
// Consider returning a slice or something like that
@@ -91,7 +91,7 @@ impl<T: ExtractAnimationTime + Sync> ExtractAnimationTime for Option<T> {
9191
}
9292
}
9393
impl<T: ExtractIndex> ExtractIndex for Option<T> {
94-
fn try_index(&self) -> Option<usize> {
94+
fn try_index(&self) -> Option<Vec<usize>> {
9595
self.as_ref().and_then(|x| x.try_index())
9696
}
9797
}
@@ -122,7 +122,7 @@ impl<T: ExtractAnimationTime + Sync> ExtractAnimationTime for Arc<T> {
122122
}
123123
}
124124
impl<T: ExtractIndex> ExtractIndex for Arc<T> {
125-
fn try_index(&self) -> Option<usize> {
125+
fn try_index(&self) -> Option<Vec<usize>> {
126126
(**self).try_index()
127127
}
128128
}
@@ -170,8 +170,8 @@ impl ExtractTime for ContextImpl<'_> {
170170
}
171171
}
172172
impl ExtractIndex for ContextImpl<'_> {
173-
fn try_index(&self) -> Option<usize> {
174-
self.index
173+
fn try_index(&self) -> Option<Vec<usize>> {
174+
self.index.clone()
175175
}
176176
}
177177
impl ExtractVarArgs for ContextImpl<'_> {
@@ -202,8 +202,8 @@ impl ExtractAnimationTime for OwnedContextImpl {
202202
}
203203
}
204204
impl ExtractIndex for OwnedContextImpl {
205-
fn try_index(&self) -> Option<usize> {
206-
self.index
205+
fn try_index(&self) -> Option<Vec<usize>> {
206+
self.index.clone()
207207
}
208208
}
209209
impl ExtractVarArgs for OwnedContextImpl {
@@ -244,7 +244,7 @@ pub struct OwnedContextImpl {
244244
varargs: Option<Arc<[DynBox]>>,
245245
parent: Option<Arc<dyn ExtractVarArgs + Sync + Send>>,
246246
// This could be converted into a single enum to save extra bytes
247-
index: Option<usize>,
247+
index: Option<Vec<usize>>,
248248
real_time: Option<f64>,
249249
animation_time: Option<f64>,
250250
}
@@ -334,7 +334,11 @@ impl OwnedContextImpl {
334334
self
335335
}
336336
pub fn with_index(mut self, index: usize) -> Self {
337-
self.index = Some(index);
337+
if let Some(current_index) = &mut self.index {
338+
current_index.push(index);
339+
} else {
340+
self.index = Some(vec![index]);
341+
}
338342
self
339343
}
340344
pub fn into_context(self) -> Option<Arc<Self>> {
@@ -346,12 +350,12 @@ impl OwnedContextImpl {
346350
}
347351
}
348352

349-
#[derive(Default, Clone, Copy, dyn_any::DynAny)]
353+
#[derive(Default, Clone, dyn_any::DynAny)]
350354
pub struct ContextImpl<'a> {
351355
pub(crate) footprint: Option<&'a Footprint>,
352356
varargs: Option<&'a [DynRef<'a>]>,
353357
// This could be converted into a single enum to save extra bytes
354-
index: Option<usize>,
358+
index: Option<Vec<usize>>,
355359
time: Option<f64>,
356360
}
357361

@@ -363,6 +367,7 @@ impl<'a> ContextImpl<'a> {
363367
ContextImpl {
364368
footprint: Some(new_footprint),
365369
varargs: varargs.map(|x| x.borrow()),
370+
index: self.index.clone(),
366371
..*self
367372
}
368373
}

node-graph/gcore/src/vector/algorithms/instance.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,10 @@ async fn instance_position(ctx: impl Ctx + ExtractVarArgs) -> DVec2 {
8888

8989
// TODO: Make this return a u32 instead of an f64, but we ned to improve math-related compatibility with integer types first.
9090
#[node_macro::node(category("Instancing"), path(graphene_core::vector))]
91-
async fn instance_index(ctx: impl Ctx + ExtractIndex) -> f64 {
92-
match ctx.try_index() {
93-
Some(index) => return index as f64,
94-
None => warn!("Extracted value of incorrect type"),
95-
}
96-
0.
91+
async fn instance_index(ctx: impl Ctx + ExtractIndex, _primary: (), loop_level: u32) -> f64 {
92+
ctx.try_index()
93+
.and_then(|indexes| indexes.get(indexes.len().wrapping_sub(1).wrapping_sub(loop_level as usize)).copied())
94+
.unwrap_or_default() as f64
9795
}
9896

9997
#[cfg(test)]

0 commit comments

Comments
 (0)