Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion demo-artwork/changing-seasons.graphite

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion demo-artwork/isometric-fountain.graphite

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion demo-artwork/marbled-mandelbrot.graphite

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion demo-artwork/painted-dreams.graphite

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion demo-artwork/parametric-dunescape.graphite

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion demo-artwork/procedural-string-lights.graphite

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion demo-artwork/red-dress.graphite

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion demo-artwork/valley-of-spires.graphite

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -466,22 +466,22 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
// [IMPORTS]2 -> 0[0:Floor]
// [0:Floor]0 -> 0[1:Subtract]
// "1: f64" -> 1[1:Subtract]
// "(): ()" -> 0[2:Instance Index]
// "0: u32" -> 1[2:Instance Index]
// [2:Instance Index]0 -> 0[3:Divide]
// "(): ()" -> 0[2:Read Index]
// "0: u32" -> 1[2:Read Index]
// [2:Read Index]0 -> 0[3:Divide]
// [1:Subtract]0 -> 1[3:Divide]
// [IMPORTS]1 -> 0[4:Position on Path]
// [3:Divide]0 -> 1[4:Position on Path]
// "false: bool" -> 2[4:Position on Path]
// "false: bool" -> 3[4:Position on Path]
// "(): ()" -> 0[5:Instance Vector]
// [5:Instance Vector]0 -> 0[6:Reset Transform]
// "(): ()" -> 0[5:Read Vector]
// [5:Read Vector]0 -> 0[6:Reset Transform]
// "true: bool" -> 1[6:Reset Transform]
// "false: bool" -> 2[6:Reset Transform]
// "false: bool" -> 3[6:Reset Transform]
// [12:Flatten Vector]0 -> 0[7:Instance Map]
// [6:Reset Transform]0 -> 1[7:Instance Map]
// [7:Instance Map]0 -> 0[8:Morph]
// [12:Flatten Vector]0 -> 0[7:Map Vector]
// [6:Reset Transform]0 -> 1[7:Map Vector]
// [7:Map Vector]0 -> 0[8:Morph]
// [15:Multiply]0 -> 1[8:Morph]
// [8:Morph]0 -> 0[9:Transform]
// [4:Position on Path]0 -> 1[9:Transform]
Expand Down Expand Up @@ -523,9 +523,9 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
inputs: vec![NodeInput::node(NodeId(0), 0), NodeInput::value(TaggedValue::F64(1.), false)],
..Default::default()
},
// 2: Instance Index
// 2: Read Index
DocumentNode {
implementation: DocumentNodeImplementation::ProtoNode(vector_nodes::instance_index::IDENTIFIER),
implementation: DocumentNodeImplementation::ProtoNode(context::read_index::IDENTIFIER),
inputs: vec![NodeInput::value(TaggedValue::None, false), NodeInput::value(TaggedValue::U32(0), false)],
..Default::default()
},
Expand All @@ -546,9 +546,9 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
],
..Default::default()
},
// 5: Instance Vector
// 5: Read Vector
DocumentNode {
implementation: DocumentNodeImplementation::ProtoNode(vector_nodes::instance_vector::IDENTIFIER),
implementation: DocumentNodeImplementation::ProtoNode(context::read_vector::IDENTIFIER),
inputs: vec![NodeInput::value(TaggedValue::None, false)],
..Default::default()
},
Expand All @@ -563,9 +563,9 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
],
..Default::default()
},
// 7: Instance Map
// 7: Map Vector
DocumentNode {
implementation: DocumentNodeImplementation::ProtoNode(vector_nodes::instance_map::IDENTIFIER),
implementation: DocumentNodeImplementation::ProtoNode(vector_nodes::map_vector::IDENTIFIER),
inputs: vec![NodeInput::node(NodeId(12), 0), NodeInput::node(NodeId(6), 0)],
..Default::default()
},
Expand Down Expand Up @@ -679,7 +679,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
},
..Default::default()
},
// 2: Instance Index
// 2: Read Index
DocumentNodeMetadata {
persistent_metadata: DocumentNodePersistentMetadata {
node_type_metadata: NodeTypePersistentMetadata::node(IVec2::new(7, -2)),
Expand All @@ -703,7 +703,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
},
..Default::default()
},
// 5: Instance Vector
// 5: Read Vector
DocumentNodeMetadata {
persistent_metadata: DocumentNodePersistentMetadata {
node_type_metadata: NodeTypePersistentMetadata::node(IVec2::new(7, 2)),
Expand All @@ -719,7 +719,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
},
..Default::default()
},
// 7: Instance Map
// 7: Map Vector
DocumentNodeMetadata {
persistent_metadata: DocumentNodePersistentMetadata {
node_type_metadata: NodeTypePersistentMetadata::node(IVec2::new(21, 1)),
Expand Down Expand Up @@ -833,14 +833,14 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
DocumentNodeDefinition {
identifier: "Origins to Polyline",
category: "Vector",
// "(): ()" -> 0[0:Instance Vector]
// [0:Instance Vector]0 -> 0[1:Extract Transform]
// "(): ()" -> 0[0:Read Vector]
// [0:Read Vector]0 -> 0[1:Extract Transform]
// [1:Extract Transform]0 -> 0[2:Decompose Translation]
// [2:Decompose Translation]0 -> 0[3:Vec2 to Point]
// [IMPORTS]0 -> 0[4:Flatten Vector]
// [4:Flatten Vector]0 -> 0[5:Instance Map]
// [3:Vec2 to Point]0 -> 1[5:Instance Map]
// [5:Instance Map]0 -> 0[6: Flatten Path]
// [4:Flatten Vector]0 -> 0[5:Map Vector]
// [3:Vec2 to Point]0 -> 1[5:Map Vector]
// [5:Map Vector]0 -> 0[6: Flatten Path]
// [6:Flatten Path]0 -> 0[7:Points to Polyline]
// "false: bool" -> 1[7:Points to Polyline]
// [7:Points to Polyline]0 -> 0[EXPORTS]
Expand All @@ -849,9 +849,9 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
implementation: DocumentNodeImplementation::Network(NodeNetwork {
exports: vec![NodeInput::node(NodeId(7), 0)],
nodes: [
// 0: Instance Vector
// 0: Read Vector
DocumentNode {
implementation: DocumentNodeImplementation::ProtoNode(vector_nodes::instance_vector::IDENTIFIER),
implementation: DocumentNodeImplementation::ProtoNode(context::read_vector::IDENTIFIER),
inputs: vec![NodeInput::value(TaggedValue::None, false)],
..Default::default()
},
Expand Down Expand Up @@ -879,9 +879,9 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
inputs: vec![NodeInput::import(generic!(T), 0)],
..Default::default()
},
// 5: Instance Map
// 5: Map Vector
DocumentNode {
implementation: DocumentNodeImplementation::ProtoNode(vector_nodes::instance_map::IDENTIFIER),
implementation: DocumentNodeImplementation::ProtoNode(vector_nodes::map_vector::IDENTIFIER),
inputs: vec![NodeInput::node(NodeId(4), 0), NodeInput::node(NodeId(3), 0)],
..Default::default()
},
Expand Down Expand Up @@ -914,7 +914,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
network_metadata: Some(NodeNetworkMetadata {
persistent_metadata: NodeNetworkPersistentMetadata {
node_metadata: [
// 0: Instance Vector
// 0: Read Vector
DocumentNodeMetadata {
persistent_metadata: DocumentNodePersistentMetadata {
node_type_metadata: NodeTypePersistentMetadata::node(IVec2::new(0, 1)),
Expand Down Expand Up @@ -954,7 +954,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
},
..Default::default()
},
// 5: Instance Map
// 5: Map Vector
DocumentNodeMetadata {
persistent_metadata: DocumentNodePersistentMetadata {
node_type_metadata: NodeTypePersistentMetadata::node(IVec2::new(28, 0)),
Expand Down
22 changes: 11 additions & 11 deletions editor/src/messages/portfolio/document_migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -834,27 +834,27 @@ const NODE_REPLACEMENTS: &[NodeReplacement<'static>] = &[
aliases: &["graphene_core::vector::generator_nodes::StarNode"],
},
NodeReplacement {
node: graphene_std::vector::instance_index::IDENTIFIER,
aliases: &["graphene_core::vector::InstanceIndexNode"],
node: graphene_std::context::read_index::IDENTIFIER,
aliases: &["graphene_core::vector::InstanceIndexNode", "core_types::vector::InstanceIndexNode"],
},
NodeReplacement {
node: graphene_std::vector::instance_map::IDENTIFIER,
node: graphene_std::vector::map_vector::IDENTIFIER,
aliases: &["graphene_core::vector::InstanceMapNode"],
},
NodeReplacement {
node: graphene_std::vector::instance_on_points::IDENTIFIER,
aliases: &["graphene_core::vector::InstanceOnPointsNode"],
},
NodeReplacement {
node: graphene_std::vector::instance_position::IDENTIFIER,
aliases: &["graphene_core::vector::InstancePositionNode"],
node: graphene_std::context::read_position::IDENTIFIER,
aliases: &["graphene_core::vector::InstancePositionNode", "core_types::vector::InstancePositionNode"],
},
NodeReplacement {
node: graphene_std::vector::instance_repeat::IDENTIFIER,
aliases: &["graphene_core::vector::InstanceRepeatNode"],
},
NodeReplacement {
node: graphene_std::vector::instance_vector::IDENTIFIER,
node: graphene_std::context::read_vector::IDENTIFIER,
aliases: &["graphene_core::vector::InstanceVectorNode"],
},
NodeReplacement {
Expand Down Expand Up @@ -1546,11 +1546,11 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
}
}

// Add the "Depth" parameter to the "Instance Index" node
if reference == DefinitionIdentifier::ProtoNode(graphene_std::vector::instance_index::IDENTIFIER) && inputs_count == 0 {
// Add the "Depth" parameter to the "Read Index" node
if reference == DefinitionIdentifier::ProtoNode(graphene_std::context::read_index::IDENTIFIER) && inputs_count == 0 {
let mut node_template = resolve_document_node_type(&reference)?.default_node_template();
document.network_interface.replace_implementation(node_id, network_path, &mut node_template);
document.network_interface.set_display_name(node_id, "Instance Index".to_string(), network_path);
document.network_interface.set_display_name(node_id, "Read Index".to_string(), network_path);

let mut node_path = network_path.to_vec();
node_path.push(*node_id);
Expand Down Expand Up @@ -1646,8 +1646,8 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
.set_input(&InputConnector::node(*node_id, 1), NodeInput::value(TaggedValue::F64(1.), false), network_path);
}

// Upgrade the "Instance Position" node to add the "Loop Level" input
if reference == DefinitionIdentifier::ProtoNode(graphene_std::vector_nodes::instance::instance_position::IDENTIFIER) && inputs_count < 2 {
// Upgrade the "Read Position" node to add the "Loop Level" input
if reference == DefinitionIdentifier::ProtoNode(graphene_std::context::read_position::IDENTIFIER) && inputs_count < 2 {
let mut node_template = resolve_document_node_type(&reference)?.default_node_template();
document.network_interface.replace_implementation(node_id, network_path, &mut node_template);
let _ = document.network_interface.replace_inputs(node_id, network_path, &mut node_template);
Expand Down
43 changes: 43 additions & 0 deletions node-graph/nodes/gcore/src/context.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use core_types::ExtractVarArgs;
use core_types::table::Table;
use core_types::{Ctx, ExtractIndex, ExtractPosition};
use glam::DVec2;
use graphic_types::Vector;

// TODO: Call this "Read Context" once it's fully generic
#[node_macro::node(category("Context"), path(graphene_core::vector))]
fn read_vector(ctx: impl Ctx + ExtractVarArgs) -> Table<Vector> {
let Ok(var_arg) = ctx.vararg(0) else { return Default::default() };
let var_arg = var_arg as &dyn std::any::Any;

var_arg.downcast_ref().cloned().unwrap_or_default()
}

#[node_macro::node(category("Context"), path(core_types::vector))]
async fn read_position(
ctx: impl Ctx + ExtractPosition,
_primary: (),
/// The number of nested loops to traverse outwards (from the innermost loop) to get the position from. The most upstream loop is level 0, and downstream loops add levels.
///
/// In programming terms: inside the double loop `i { j { ... } }`, *Loop Level* 0 = `j` and 1 = `i`. After inserting a third loop `k { ... }`, inside it, levels would be 0 = `k`, 1 = `j`, and 2 = `i`.
loop_level: u32,
) -> DVec2 {
ctx.try_position().and_then(|mut iter| iter.nth(loop_level as usize).or_else(|| iter.last())).unwrap_or(DVec2::ZERO)
}

// TODO: Return u32, u64, or usize instead of f64 after #1621 is resolved and has allowed us to implement automatic type conversion in the node graph for nodes with generic type inputs.
// TODO: (Currently automatic type conversion only works for concrete types, via the Graphene preprocessor and not the full Graphene type system.)
/// Produces the index of the current iteration of a loop by reading from the evaluation context, which is supplied by downstream nodes such as *Instance Repeat*.
///
/// Nested loops can enable 2D or higher-dimensional iteration by using the *Loop Level* parameter to read the index from outer levels of loops.
#[node_macro::node(category("Context"), path(core_types::vector))]
async fn read_index(
ctx: impl Ctx + ExtractIndex,
_primary: (),
/// The number of nested loops to traverse outwards (from the innermost loop) to get the index from. The most upstream loop is level 0, and downstream loops add levels.
///
/// In programming terms: inside the double loop `i { j { ... } }`, *Loop Level* 0 = `j` and 1 = `i`. After inserting a third loop `k { ... }`, inside it, levels would be 0 = `k`, 1 = `j`, and 2 = `i`.
loop_level: u32,
) -> f64 {
ctx.try_index().and_then(|mut iter| iter.nth(loop_level as usize).or_else(|| iter.last())).unwrap_or(0) as f64
}
2 changes: 2 additions & 0 deletions node-graph/nodes/gcore/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod animation;
pub mod context;
pub mod context_modification;
pub mod debug;
pub mod extract_xy;
Expand All @@ -8,6 +9,7 @@ pub mod ops;

// Re-export all nodes
pub use animation::*;
pub use context::*;
pub use context_modification::*;
pub use debug::*;
pub use extract_xy::*;
Expand Down
10 changes: 5 additions & 5 deletions node-graph/nodes/gstd/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ pub mod render_node;
pub mod text;
#[cfg(feature = "wasm")]
pub mod wasm_application_io;

pub use blending_nodes;
pub use brush_nodes as brush;
pub use core_types::*;
pub use graphene_application_io as application_io;
pub use graphene_core;
pub use graphene_core::debug;
pub use graphic_nodes;
pub use graphic_types::{Artboard, Graphic, Vector};
pub use math_nodes;
pub use path_bool_nodes as path_bool;
pub use raster_nodes;
Expand Down Expand Up @@ -75,7 +76,9 @@ pub mod logic {
pub use graphene_core::logic::*;
}

pub use graphene_core::debug;
pub mod context {
pub use graphene_core::context::*;
}

// Re-export graphene_core modules for backward compatibility
pub mod ops {
Expand All @@ -91,9 +94,6 @@ pub mod animation {
pub use graphene_core::animation::*;
}

// Re-export at top level for convenience
pub use graphic_types::{Artboard, Graphic, Vector};

/// stop gap solutions until all paths have been replaced with their absolute ones
pub mod renderer {
pub use core_types::math::quad::Quad;
Expand Down
57 changes: 3 additions & 54 deletions node-graph/nodes/vector/src/instance.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use core_types::Color;
use core_types::table::{Table, TableRowRef};
use core_types::{CloneVarArgs, Context, Ctx, ExtractAll, ExtractIndex, ExtractPosition, OwnedContextImpl};
use glam::DVec2;
use core_types::{CloneVarArgs, Context, Ctx, ExtractAll, OwnedContextImpl};
use graphic_types::Graphic;
use graphic_types::Vector;
use graphic_types::raster_types::{CPU, Raster};
Expand Down Expand Up @@ -83,58 +82,14 @@ async fn instance_repeat<T: Into<Graphic> + Default + Send + Clone + 'static>(
result_table
}

#[node_macro::node(category("Instancing"), path(core_types::vector))]
async fn instance_position(
ctx: impl Ctx + ExtractPosition,
_primary: (),
/// The number of nested loops to traverse outwards (from the innermost loop) to get the position from. The most upstream loop is level 0, and downstream loops add levels.
///
/// In programming terms: inside the double loop `i { j { ... } }`, *Loop Level* 0 = `j` and 1 = `i`. After inserting a third loop `k { ... }`, inside it, levels would be 0 = `k`, 1 = `j`, and 2 = `i`.
loop_level: u32,
) -> DVec2 {
let Some(position_iter) = ctx.try_position() else { return DVec2::ZERO };
let mut last = DVec2::ZERO;
for (i, position) in position_iter.enumerate() {
if i == loop_level as usize {
return position;
}
last = position;
}
last
}

// TODO: Return u32, u64, or usize instead of f64 after #1621 is resolved and has allowed us to implement automatic type conversion in the node graph for nodes with generic type inputs.
// TODO: (Currently automatic type conversion only works for concrete types, via the Graphene preprocessor and not the full Graphene type system.)
/// Produces the index of the current iteration of a loop by reading from the evaluation context, which is supplied by downstream nodes such as *Instance Repeat*.
///
/// Nested loops can enable 2D or higher-dimensional iteration by using the *Loop Level* parameter to read the index from outer levels of loops.
#[node_macro::node(category("Instancing"), path(core_types::vector))]
async fn instance_index(
ctx: impl Ctx + ExtractIndex,
_primary: (),
/// The number of nested loops to traverse outwards (from the innermost loop) to get the index from. The most upstream loop is level 0, and downstream loops add levels.
///
/// In programming terms: inside the double loop `i { j { ... } }`, *Loop Level* 0 = `j` and 1 = `i`. After inserting a third loop `k { ... }`, inside it, levels would be 0 = `k`, 1 = `j`, and 2 = `i`.
loop_level: u32,
) -> f64 {
let Some(index_iter) = ctx.try_index() else { return 0. };
let mut last = 0;
for (i, index) in index_iter.enumerate() {
if i == loop_level as usize {
return index as f64;
}
last = index;
}
last as f64
}

#[cfg(test)]
mod test {
use super::*;
use crate::generator_nodes::RectangleNode;
use core_types::Ctx;
use core_types::Node;
use glam::DVec2;
use graphene_core::ReadPositionNode;
use graphene_core::extract_xy::{ExtractXyNode, XY};
use graphic_types::Vector;
use std::future::Future;
Expand All @@ -157,13 +112,7 @@ mod test {
let owned = OwnedContextImpl::default().into_context();
let rect = RectangleNode::new(
FutureWrapperNode(()),
ExtractXyNode::new(
InstancePositionNode {
_primary: FutureWrapperNode(()),
loop_level: FutureWrapperNode(0),
},
FutureWrapperNode(XY::Y),
),
ExtractXyNode::new(ReadPositionNode::new(FutureWrapperNode(()), FutureWrapperNode(0)), FutureWrapperNode(XY::Y)),
FutureWrapperNode(2_f64),
FutureWrapperNode(false),
FutureWrapperNode(0_f64),
Expand Down
Loading