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
Original file line number Diff line number Diff line change
Expand Up @@ -787,9 +787,9 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
inputs: vec![NodeInput::node(NodeId(1), 0)],
..Default::default()
},
// 3: Vec2 to Point
// 3: As Vector (auto-converts the decomposed translation into a single-anchor List<Vector>)
DocumentNode {
implementation: DocumentNodeImplementation::ProtoNode(vector_nodes::vec_2_to_point::IDENTIFIER),
implementation: DocumentNodeImplementation::ProtoNode(vector::as_vector::IDENTIFIER),
inputs: vec![NodeInput::node(NodeId(2), 0)],
..Default::default()
},
Expand Down Expand Up @@ -858,7 +858,7 @@ fn document_node_definitions() -> HashMap<DefinitionIdentifier, DocumentNodeDefi
},
..Default::default()
},
// 3: Vec2 to Point
// 3: As Vector
DocumentNodeMetadata {
persistent_metadata: DocumentNodePersistentMetadata {
node_type_metadata: NodeTypePersistentMetadata::node(IVec2::new(21, 1)),
Expand Down
19 changes: 11 additions & 8 deletions editor/src/messages/portfolio/document_migration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -404,16 +404,16 @@ const NODE_REPLACEMENTS: &[NodeReplacement<'static>] = &[
aliases: &["graphene_math_nodes::TangentInverseNode", "graphene_core::ops::TangentInverseNode"],
},
NodeReplacement {
node: graphene_std::math_nodes::to_f_64::IDENTIFIER,
aliases: &["graphene_math_nodes::ToF64Node", "graphene_core::ops::ToF64Node"],
node: graphene_std::math_nodes::as_f_64::IDENTIFIER,
aliases: &["graphene_math_nodes::ToF64Node", "graphene_core::ops::ToF64Node", "math_nodes::ToF64Node"],
},
NodeReplacement {
node: graphene_std::math_nodes::to_u_32::IDENTIFIER,
node: graphene_std::math_nodes::as_u_32::IDENTIFIER,
aliases: &["graphene_math_nodes::ToU32Node", "graphene_core::ops::ToU32Node", "math_nodes::ToU32Node"],
},
NodeReplacement {
node: graphene_std::math_nodes::to_u_64::IDENTIFIER,
aliases: &["graphene_math_nodes::ToU64Node", "graphene_core::ops::ToU64Node"],
node: graphene_std::math_nodes::as_u_64::IDENTIFIER,
aliases: &["graphene_math_nodes::ToU64Node", "graphene_core::ops::ToU64Node", "math_nodes::ToU64Node"],
},
NodeReplacement {
node: graphene_std::math_nodes::vec_2_value::IDENTIFIER,
Expand Down Expand Up @@ -676,8 +676,8 @@ const NODE_REPLACEMENTS: &[NodeReplacement<'static>] = &[
aliases: &["graphene_core::logic::SwitchNode"],
},
NodeReplacement {
node: graphene_std::text_nodes::to_string::IDENTIFIER,
aliases: &["graphene_core::logic::ToStringNode"],
node: graphene_std::text_nodes::as_string::IDENTIFIER,
aliases: &["graphene_core::logic::ToStringNode", "text_nodes::ToStringNode"],
},
NodeReplacement {
node: graphene_std::text_nodes::json::query_json::IDENTIFIER,
Expand Down Expand Up @@ -958,11 +958,12 @@ const NODE_REPLACEMENTS: &[NodeReplacement<'static>] = &[
aliases: &["graphene_core::vector::TangentOnPathNode"],
},
NodeReplacement {
node: graphene_std::vector::vec_2_to_point::IDENTIFIER,
node: graphene_std::vector::as_vector::IDENTIFIER,
aliases: &[
"graphene_core::vector::vector_nodes::PositionToPointNode",
"graphene_core::vector::PositionToPointNode",
"graphene_core::vector::Vec2ToPointNode",
"core_types::vector::Vec2ToPointNode",
],
},
];
Expand Down Expand Up @@ -1574,6 +1575,8 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
for i in 10..=12 {
document.network_interface.set_input(&InputConnector::node(*node_id, i), old_inputs[i - 2].clone(), network_path);
}

inputs_count = 13;
}

// Upgrade Sine, Cosine, and Tangent nodes to include a boolean input for whether the output should be in radians, which was previously the only option but is now not the default
Expand Down
3 changes: 2 additions & 1 deletion node-graph/interpreted-executor/src/node_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
// INTO NODES
// ==========
into_node!(from: List<Graphic>, to: List<Graphic>),
into_node!(from: List<Vector>, to: List<Vector>),
into_node!(from: List<Raster<CPU>>, to: List<Raster<CPU>>),
#[cfg(feature = "gpu")]
into_node!(from: List<Raster<GPU>>, to: List<Raster<GPU>>),
Expand Down Expand Up @@ -96,6 +95,8 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
#[cfg(feature = "gpu")]
into_node!(from: &PlatformEditorApi, to: &WgpuExecutor),
convert_node!(from: DVec2, to: DVec2),
convert_node!(from: List<Vector>, to: List<Vector>),
convert_node!(from: DVec2, to: List<Vector>),
convert_node!(from: String, to: String),
convert_node!(from: bool, to: String),
convert_node!(from: DVec2, to: String),
Expand Down
14 changes: 13 additions & 1 deletion node-graph/libraries/core-types/src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,19 @@ impl Convert<DVec2, ()> for DVec2 {
}
}

// TODO: Add a DVec2 to List<Vector> anchor point conversion implementation to replace the 'Vec2 to Point' node
/// Constructs `Self` from a single anchor point at the given position. Implemented by the vector crate's
/// path type so the `Convert` impl below can build a single-point path without core-types depending on
/// that crate (mirroring how [`ListConvert`] bridges per-item list conversions).
pub trait FromAnchorPosition {
fn from_anchor_position(position: DVec2) -> Self;
}

// Converts a position into a vector path composed of a single anchor point
impl<T: FromAnchorPosition + Send> Convert<List<T>, ()> for DVec2 {
async fn convert(self, _: Footprint, _: ()) -> List<T> {
List::new_from_item(Item::new_from_element(T::from_anchor_position(self)))
}
}

/// Implements the [`Convert`] trait for conversion between the cartesian product of Rust's primitive numeric types.
macro_rules! impl_convert {
Expand Down
2 changes: 1 addition & 1 deletion node-graph/libraries/core-types/src/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,6 @@ impl ApplyTransform for DVec2 {
*self = modification.transform_point2(*self);
}
fn left_apply_transform(&mut self, modification: &DAffine2) {
*self = modification.inverse().transform_point2(*self);
*self = modification.transform_point2(*self);
}
}
11 changes: 9 additions & 2 deletions node-graph/libraries/graphic-types/src/graphic.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use core_types::bounds::{BoundingBox, RenderBoundingBox};
use core_types::graphene_hash::CacheHash;
use core_types::list::{ATTR_FILL, ATTR_STROKE, Item, List};
use core_types::ops::ListConvert;
use core_types::ops::{FromAnchorPosition, ListConvert};
use core_types::render_complexity::RenderComplexity;
use core_types::uuid::NodeId;
use core_types::{ATTR_CLIPPING_MASK, ATTR_EDITOR_LAYER_PATH, ATTR_GRADIENT_TYPE, ATTR_OPACITY, ATTR_OPACITY_FILL, ATTR_SPREAD_METHOD, ATTR_TRANSFORM, Color};
use dyn_any::DynAny;
use glam::DAffine2;
use glam::{DAffine2, DVec2};
use raster_types::{CPU, GPU, Raster};
use std::borrow::Cow;
use vector_types::GradientStops;
Expand Down Expand Up @@ -393,6 +393,13 @@ impl From<DAffine2> for Graphic {
Graphic::default()
}
}

// DVec2
impl From<DVec2> for Graphic {
fn from(position: DVec2) -> Self {
Graphic::Vector(List::new_from_element(Vector::from_anchor_position(position)))
}
}
// Note: List conversions handled by blanket impl in gcore

impl Graphic {
Expand Down
30 changes: 30 additions & 0 deletions node-graph/libraries/vector-types/src/vector/vector_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,23 @@ impl graphene_hash::CacheHash for Vector {
}
}

impl core_types::ops::FromAnchorPosition for Vector {
fn from_anchor_position(position: DVec2) -> Self {
let mut point_domain = PointDomain::new();
point_domain.push(PointId::generate(), position);

Self { point_domain, ..Default::default() }
}
}

// Identity item conversion so `List<Vector>` satisfies the blanket `Convert<List<U>, ()> for List<T>`, letting its

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we make this less verbose?

// auto-inserted input wrapper be a `ConvertNode` (which also accepts a `DVec2` anchor position) rather than an `IntoNode`.
impl core_types::ops::ListConvert<Vector> for Vector {
fn convert_item(self) -> Vector {
self
}
}

impl Vector {
/// Add a subpath to this vector path.
pub fn append_subpath(&mut self, subpath: impl Borrow<Subpath<PointId>>, preserve_id: bool) {
Expand Down Expand Up @@ -619,4 +636,17 @@ mod tests {
let generated = vector.stroke_bezier_paths().collect::<Vec<_>>();
assert_subpath_eq(&generated, &[curve, circle]);
}

// Verifies the `DVec2 -> List<Vector>` conversion that replaced the former "Vec2 to Point" node yields a path
// with exactly one anchor point at the given position and no segments
#[test]
fn anchor_position_builds_single_point_path() {
use core_types::ops::FromAnchorPosition;

let vector = Vector::from_anchor_position(DVec2::new(3., 4.));

assert_eq!(vector.point_domain.positions(), [DVec2::new(3., 4.)]);
assert_eq!(vector.point_domain.ids().len(), 1);
assert!(vector.segment_domain.ids().is_empty());
}
}
1 change: 1 addition & 0 deletions node-graph/nodes/graphic/src/graphic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,7 @@ pub async fn wrap_graphic<T: Into<Graphic> + 'n>(
List<Color>,
List<GradientStops>,
DAffine2,
DVec2,
)]
content: T,
) -> List<Graphic> {
Expand Down
12 changes: 6 additions & 6 deletions node-graph/nodes/math/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,22 +421,22 @@ fn random(

// TODO: Test that these are no longer needed in all circumstances, then remove them and add a migration to convert these into Passthrough nodes. Note: these act more as type annotations than as identity functions.
/// Convert a number to an integer of the type u32, which may be the required type for certain node inputs.
#[node_macro::node(name("To u32"), category("Debug"))]
fn to_u32(_: impl Ctx, value: u32) -> u32 {
#[node_macro::node(name("As u32"), category("Debug"))]
fn as_u32(_: impl Ctx, value: u32) -> u32 {
value
}

// TODO: Test that these are no longer needed in all circumstances, then remove them and add a migration to convert these into Passthrough nodes. Note: these act more as type annotations than as identity functions.
/// Convert a number to an integer of the type u64, which may be the required type for certain node inputs.
#[node_macro::node(name("To u64"), category("Debug"))]
fn to_u64(_: impl Ctx, value: u64) -> u64 {
#[node_macro::node(name("As u64"), category("Debug"))]
fn as_u64(_: impl Ctx, value: u64) -> u64 {
value
}

// TODO: Test that these are no longer needed in all circumstances, then remove them and add a migration to convert these into Passthrough nodes. Note: these act more as type annotations than as identity functions.
/// Convert an integer to a decimal number of the type f64, which may be the required type for certain node inputs.
#[node_macro::node(name("To f64"), category("Debug"))]
fn to_f64(_: impl Ctx, value: f64) -> f64 {
#[node_macro::node(name("As f64"), category("Debug"))]
fn as_f64(_: impl Ctx, value: f64) -> f64 {
value
}

Expand Down
2 changes: 1 addition & 1 deletion node-graph/nodes/text/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ fn string_value(_: impl Ctx, _primary: (), string: TextArea) -> String {

/// Type-asserts a value to be a string.
#[node_macro::node(category("Debug"))]
fn to_string(_: impl Ctx, value: String) -> String {
fn as_string(_: impl Ctx, value: String) -> String {
value
}

Expand Down
14 changes: 4 additions & 10 deletions node-graph/nodes/vector/src/vector_nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1074,16 +1074,10 @@ async fn dimensions(_: impl Ctx, content: List<Vector>) -> DVec2 {
.unwrap_or_default()
}

// TODO: Replace this node with an automatic type conversion implementation of the `Convert` trait
/// Converts a vec2 value into a vector path composed of a single anchor point.
///
/// This is useful in conjunction with nodes that repeat it, followed by the "Points to Polyline" node to string together a path of the points.
#[node_macro::node(category("Vector"), name("Vec2 to Point"), path(core_types::vector))]
async fn vec2_to_point(_: impl Ctx, vec2: DVec2) -> List<Vector> {
let mut point_domain = PointDomain::new();
point_domain.push(PointId::generate(), vec2);

List::new_from_item(Item::new_from_element(Vector { point_domain, ..Default::default() }))
/// Type-asserts a value to be vector data.
#[node_macro::node(category("Vector"), name("As Vector"), path(core_types::vector))]
fn as_vector(_: impl Ctx, value: List<Vector>) -> List<Vector> {
value
}

/// Creates a polyline from a series of vector points, replacing any existing segments and regions that may already exist.
Expand Down
Loading