From 4c64df038fa3ca9d1c1fb2f5419bb2ef5b92a4fd Mon Sep 17 00:00:00 2001 From: 0HyperCube <78500760+0HyperCube@users.noreply.github.com> Date: Wed, 3 Jan 2024 12:21:10 +0000 Subject: [PATCH] Copy to Points node: add support for groups (#1541) Copy to points by group --- node-graph/gcore/src/vector/vector_nodes.rs | 60 ++++++++++++------- .../interpreted-executor/src/node_registry.rs | 1 + 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/node-graph/gcore/src/vector/vector_nodes.rs b/node-graph/gcore/src/vector/vector_nodes.rs index 89415993..ade2d5cd 100644 --- a/node-graph/gcore/src/vector/vector_nodes.rs +++ b/node-graph/gcore/src/vector/vector_nodes.rs @@ -1,7 +1,8 @@ use super::style::{Fill, FillType, Gradient, GradientType, Stroke}; use super::VectorData; -use crate::transform::Footprint; -use crate::{Color, Node}; +use crate::renderer::GraphicElementRendered; +use crate::transform::{Footprint, Transform, TransformMut}; +use crate::{Color, GraphicGroup, Node}; use core::future::Future; use bezier_rs::{Subpath, SubpathTValue}; @@ -145,6 +146,34 @@ fn generate_bounding_box(vector_data: VectorData) -> VectorData { )]) } +pub trait ConcatElement { + fn concat(&mut self, other: &Self, transform: DAffine2); +} + +impl ConcatElement for VectorData { + fn concat(&mut self, other: &Self, transform: DAffine2) { + for mut subpath in other.subpaths.iter().cloned() { + subpath.apply_transform(transform * other.transform); + self.subpaths.push(subpath); + } + // TODO: properly deal with fills such as gradients + self.style = other.style.clone(); + self.mirror_angle.extend(other.mirror_angle.iter().copied()); + self.alpha_blending = other.alpha_blending; + } +} + +impl ConcatElement for GraphicGroup { + fn concat(&mut self, other: &Self, transform: DAffine2) { + // TODO: Decide if we want to keep this behaviour whereby the layers are flattened + for mut element in other.iter().cloned() { + *element.transform_mut() = transform * element.transform() * other.transform(); + self.push(element); + } + self.alpha_blending = other.alpha_blending; + } +} + #[derive(Debug, Clone, Copy)] pub struct CopyToPoints { points: Points, @@ -152,37 +181,26 @@ pub struct CopyToPoints { } #[node_macro::node_fn(CopyToPoints)] -async fn copy_to_points, FI: Future>( +async fn copy_to_points, FI: Future>( footprint: Footprint, points: impl Node, instance: impl Node, -) -> VectorData { - // TODO: https://github.com/GraphiteEditor/Graphite/pull/1536#discussion_r1436422419 +) -> I { let points = self.points.eval(footprint).await; let instance = self.instance.eval(footprint).await; let points_list = points.subpaths.iter().flat_map(|s| s.anchors()); - let instance_bounding_box = instance.bounding_box_with_transform(instance.transform).unwrap_or_default(); - let instance_center = DAffine2::from_translation(-0.5 * (instance_bounding_box[0] + instance_bounding_box[1])); + let instance_bounding_box = instance.bounding_box(DAffine2::IDENTITY).unwrap_or_default(); + let instance_center = -0.5 * (instance_bounding_box[0] + instance_bounding_box[1]); - let mut instanced_subpaths: Vec> = Vec::new(); + let mut result = I::default(); for point in points_list { - let transform = DAffine2::from_translation(points.transform.transform_point2(point)) * instance_center; - - for mut subpath in instance.subpaths.clone() { - subpath.apply_transform(transform * instance.transform); - instanced_subpaths.push(subpath); - } + let translation = points.transform.transform_point2(point) + instance_center; + result.concat(&instance, DAffine2::from_translation(translation)); } - VectorData { - subpaths: instanced_subpaths, - transform: DAffine2::IDENTITY, - style: instance.style, - alpha_blending: instance.alpha_blending, - mirror_angle: instance.mirror_angle, - } + result } #[derive(Debug, Clone, Copy)] diff --git a/node-graph/interpreted-executor/src/node_registry.rs b/node-graph/interpreted-executor/src/node_registry.rs index 9c616a55..48f25631 100644 --- a/node-graph/interpreted-executor/src/node_registry.rs +++ b/node-graph/interpreted-executor/src/node_registry.rs @@ -733,6 +733,7 @@ fn node_registry() -> HashMap, input: Footprint, params: [ImageFrame]), register_node!(graphene_std::raster::MandelbrotNode, input: Footprint, params: []), async_node!(graphene_core::vector::CopyToPoints<_, _>, input: Footprint, output: VectorData, fn_params: [Footprint => VectorData, Footprint => VectorData]), + async_node!(graphene_core::vector::CopyToPoints<_, _>, input: Footprint, output: GraphicGroup, fn_params: [Footprint => VectorData, Footprint => GraphicGroup]), register_node!(graphene_core::vector::ResamplePoints<_>, input: VectorData, params: [f64]), register_node!(graphene_core::vector::SplinesFromPointsNode, input: VectorData, params: []), register_node!(graphene_core::vector::generator_nodes::CircleGenerator<_>, input: (), params: [f32]),