Skip to content

Commit

Permalink
Migrate ArtboardGroup to ArtboardGroupTable (not yet flattened)
Browse files Browse the repository at this point in the history
  • Loading branch information
Keavon committed Mar 2, 2025
1 parent 7f4cdde commit fdab39a
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2408,7 +2408,7 @@ impl DocumentMessageHandler {
/// Create a network interface with a single export
fn default_document_network_interface() -> NodeNetworkInterface {
let mut network_interface = NodeNetworkInterface::default();
network_interface.add_export(TaggedValue::ArtboardGroup(graphene_core::ArtboardGroup::default()), -1, "", &[]);
network_interface.add_export(TaggedValue::ArtboardGroup(graphene_core::ArtboardGroupTable::default()), -1, "", &[]);
network_interface
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl<'a> ModifyInputsContext<'a> {
/// Creates an artboard as the primary export for the document network
pub fn create_artboard(&mut self, new_id: NodeId, artboard: Artboard) -> LayerNodeIdentifier {
let artboard_node_template = resolve_document_node_type("Artboard").expect("Node").node_template_input_override([
Some(NodeInput::value(TaggedValue::ArtboardGroup(graphene_std::ArtboardGroup::default()), true)),
Some(NodeInput::value(TaggedValue::ArtboardGroup(graphene_std::ArtboardGroupTable::default()), true)),
Some(NodeInput::value(TaggedValue::GraphicGroup(graphene_core::GraphicGroupTable::default()), true)),
Some(NodeInput::value(TaggedValue::IVec2(artboard.location), false)),
Some(NodeInput::value(TaggedValue::IVec2(artboard.dimensions), false)),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
DocumentNode {
manual_composition: Some(concrete!(Context)),
inputs: vec![
NodeInput::network(graphene_core::Type::Fn(Box::new(concrete!(Context)), Box::new(concrete!(ArtboardGroup))), 0),
NodeInput::network(graphene_core::Type::Fn(Box::new(concrete!(Context)), Box::new(concrete!(ArtboardGroupTable))), 0),
NodeInput::node(NodeId(1), 0),
NodeInput::Reflection(graph_craft::document::DocumentNodeMetadata::DocumentNodePath),
],
Expand All @@ -310,7 +310,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
..Default::default()
}),
inputs: vec![
NodeInput::value(TaggedValue::ArtboardGroup(ArtboardGroup::default()), true),
NodeInput::value(TaggedValue::ArtboardGroup(ArtboardGroupTable::default()), true),
NodeInput::value(TaggedValue::GraphicGroup(GraphicGroupTable::default()), true),
NodeInput::value(TaggedValue::IVec2(glam::IVec2::ZERO), false),
NodeInput::value(TaggedValue::IVec2(glam::IVec2::new(1920, 1080)), false),
Expand Down Expand Up @@ -544,7 +544,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
nodes: [
DocumentNode {
inputs: vec![NodeInput::network(concrete!(ImageFrameTable<Color>), 0)],
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::ops::IntoNode<_, ImageFrame>")), // TODO: Possibly change `ImageFrame` to something else
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::ops::IntoNode<_, ImageFrameTable>")),
..Default::default()
},
DocumentNode {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -468,8 +468,8 @@ impl NodeNetworkInterface {
InputConnector::Node { node_id, input_index } => (node_id, input_index),
InputConnector::Export(export_index) => {
let Some((encapsulating_node_id, encapsulating_node_id_path)) = network_path.split_last() else {
// The outermost network export defaults to an ArtboardGroup.
return Some((concrete!(graphene_core::ArtboardGroup), TypeSource::OuterMostExportDefault));
// The outermost network export defaults to an ArtboardGroupTable.
return Some((concrete!(graphene_core::ArtboardGroupTable), TypeSource::OuterMostExportDefault));
};

let output_type = self.output_types(encapsulating_node_id, encapsulating_node_id_path).into_iter().nth(export_index).flatten();
Expand Down
27 changes: 23 additions & 4 deletions node-graph/gcore/src/graphic_element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,25 @@ impl ArtboardGroup {
}
}

// TODO: Eventually remove this migration document upgrade code
pub fn migrate_artboard_group<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<ArtboardGroupTable, D::Error> {
use serde::Deserialize;

#[derive(serde::Serialize, serde::Deserialize)]
#[serde(untagged)]
enum EitherFormat {
ArtboardGroup(ArtboardGroup),
ArtboardGroupTable(ArtboardGroupTable),
}

Ok(match EitherFormat::deserialize(deserializer)? {
EitherFormat::ArtboardGroup(artboard_group) => ArtboardGroupTable::new(artboard_group),
EitherFormat::ArtboardGroupTable(artboard_group_table) => artboard_group_table,
})
}

pub type ArtboardGroupTable = Instances<ArtboardGroup>;

#[node_macro::node(category(""))]
async fn layer(_: impl Ctx, stack: GraphicGroupTable, mut element: GraphicElement, node_path: Vec<NodeId>) -> GraphicGroupTable {
let mut stack = stack;
Expand Down Expand Up @@ -385,15 +404,15 @@ async fn to_artboard<Data: Into<GraphicGroupTable> + 'n>(
}

#[node_macro::node(category(""))]
async fn append_artboard(_ctx: impl Ctx, mut artboards: ArtboardGroup, artboard: Artboard, node_path: Vec<NodeId>) -> ArtboardGroup {
// let mut artboards = artboards.eval(ctx.clone()).await;
// let artboard = artboard.eval(ctx).await;
async fn append_artboard(_ctx: impl Ctx, mut artboards: ArtboardGroupTable, artboard: Artboard, node_path: Vec<NodeId>) -> ArtboardGroupTable {
let artboard_group = artboards.one_instance_mut().instance;

// let foot = ctx.footprint();
// log::debug!("{:?}", foot);
// Get the penultimate element of the node path, or None if the path is too short.
// This is used to get the ID of the user-facing "Artboard" node (which encapsulates this internal "Append Artboard" node).
let encapsulating_node_id = node_path.get(node_path.len().wrapping_sub(2)).copied();
artboards.append_artboard(artboard, encapsulating_node_id);
artboard_group.append_artboard(artboard, encapsulating_node_id);

artboards
}
Expand Down
21 changes: 13 additions & 8 deletions node-graph/gcore/src/graphic_element/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::transform::{Footprint, Transform};
use crate::uuid::{generate_uuid, NodeId};
use crate::vector::style::{Fill, Stroke, ViewMode};
use crate::vector::{PointId, VectorDataTable};
use crate::{Artboard, ArtboardGroup, Color, GraphicElement, GraphicGroupTable, RasterFrame};
use crate::{Artboard, ArtboardGroupTable, Color, GraphicElement, GraphicGroupTable, RasterFrame};

use bezier_rs::Subpath;
use dyn_any::DynAny;
Expand Down Expand Up @@ -790,38 +790,43 @@ impl GraphicElementRendered for Artboard {
}
}

impl GraphicElementRendered for ArtboardGroup {
impl GraphicElementRendered for ArtboardGroupTable {
fn render_svg(&self, render: &mut SvgRender, render_params: &RenderParams) {
for (artboard, _) in &self.artboards {
for (artboard, _) in &self.one_instance().instance.artboards {
artboard.render_svg(render, render_params);
}
}

fn bounding_box(&self, transform: DAffine2) -> Option<[DVec2; 2]> {
self.artboards.iter().filter_map(|(element, _)| element.bounding_box(transform)).reduce(Quad::combine_bounds)
self.one_instance()
.instance
.artboards
.iter()
.filter_map(|(element, _)| element.bounding_box(transform))
.reduce(Quad::combine_bounds)
}

fn collect_metadata(&self, metadata: &mut RenderMetadata, footprint: Footprint, _element_id: Option<NodeId>) {
for (artboard, element_id) in &self.artboards {
for (artboard, element_id) in &self.one_instance().instance.artboards {
artboard.collect_metadata(metadata, footprint, *element_id);
}
}

fn add_upstream_click_targets(&self, click_targets: &mut Vec<ClickTarget>) {
for (artboard, _) in &self.artboards {
for (artboard, _) in &self.one_instance().instance.artboards {
artboard.add_upstream_click_targets(click_targets);
}
}

#[cfg(feature = "vello")]
fn render_to_vello(&self, scene: &mut Scene, transform: DAffine2, context: &mut RenderContext) {
for (artboard, _) in &self.artboards {
for (artboard, _) in &self.one_instance().instance.artboards {
artboard.render_to_vello(scene, transform, context)
}
}

fn contains_artboard(&self) -> bool {
!self.artboards.is_empty()
!self.one_instance().instance.artboards.is_empty()
}
}

Expand Down
31 changes: 29 additions & 2 deletions node-graph/gcore/src/instances.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use crate::application_io::{ImageTexture, TextureFrameTable};
use crate::raster::image::{Image, ImageFrameTable};
use crate::raster::Pixel;
use crate::transform::{Transform, TransformMut};
use crate::uuid::NodeId;
use crate::vector::{InstanceId, VectorData, VectorDataTable};
use crate::{AlphaBlending, GraphicElement, GraphicGroup, GraphicGroupTable, RasterFrame};

Expand All @@ -19,6 +20,7 @@ pub struct Instances<T> {
transform: Vec<DAffine2>,
#[serde(default = "one_alpha_blending_default")]
alpha_blending: Vec<AlphaBlending>,
source_node_id: Vec<Option<NodeId>>,
}

impl<T> Instances<T> {
Expand All @@ -28,6 +30,23 @@ impl<T> Instances<T> {
instance: vec![instance],
transform: vec![DAffine2::IDENTITY],
alpha_blending: vec![AlphaBlending::default()],
source_node_id: vec![None],
}
}

pub fn push(&mut self, instance: T) -> InstanceMut<T> {
self.id.push(InstanceId::generate());
self.instance.push(instance);
self.transform.push(DAffine2::IDENTITY);
self.alpha_blending.push(AlphaBlending::default());
self.source_node_id.push(None);

InstanceMut {
id: self.id.last_mut().expect("Shouldn't be empty"),
instance: self.instance.last_mut().expect("Shouldn't be empty"),
transform: self.transform.last_mut().expect("Shouldn't be empty"),
alpha_blending: self.alpha_blending.last_mut().expect("Shouldn't be empty"),
source_node_id: self.source_node_id.last_mut().expect("Shouldn't be empty"),
}
}

Expand All @@ -37,6 +56,7 @@ impl<T> Instances<T> {
instance: self.instance.first().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", self.instance.len())),
transform: self.transform.first().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", self.instance.len())),
alpha_blending: self.alpha_blending.first().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", self.instance.len())),
source_node_id: self.source_node_id.first().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", self.instance.len())),
}
}

Expand All @@ -48,6 +68,7 @@ impl<T> Instances<T> {
instance: self.instance.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", length)),
transform: self.transform.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", length)),
alpha_blending: self.alpha_blending.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", length)),
source_node_id: self.source_node_id.first_mut().unwrap_or_else(|| panic!("ONE INSTANCE EXPECTED, FOUND {}", length)),
}
}

Expand All @@ -58,11 +79,13 @@ impl<T> Instances<T> {
.zip(self.instance.iter())
.zip(self.transform.iter())
.zip(self.alpha_blending.iter())
.map(|(((id, instance), transform), alpha_blending)| Instance {
.zip(self.source_node_id.iter())
.map(|((((id, instance), transform), alpha_blending), source_node_id)| Instance {
id,
instance,
transform,
alpha_blending,
source_node_id,
})
}

Expand All @@ -73,11 +96,13 @@ impl<T> Instances<T> {
.zip(self.instance.iter_mut())
.zip(self.transform.iter_mut())
.zip(self.alpha_blending.iter_mut())
.map(|(((id, instance), transform), alpha_blending)| InstanceMut {
.zip(self.source_node_id.iter_mut())
.map(|((((id, instance), transform), alpha_blending), source_node_id)| InstanceMut {
id,
instance,
transform,
alpha_blending,
source_node_id,
})
}
}
Expand Down Expand Up @@ -121,13 +146,15 @@ pub struct Instance<'a, T> {
pub instance: &'a T,
pub transform: &'a DAffine2,
pub alpha_blending: &'a AlphaBlending,
pub source_node_id: &'a Option<NodeId>,
}
#[derive(Debug)]
pub struct InstanceMut<'a, T> {
pub id: &'a mut InstanceId,
pub instance: &'a mut T,
pub transform: &'a mut DAffine2,
pub alpha_blending: &'a mut AlphaBlending,
pub source_node_id: &'a mut Option<NodeId>,
}

// GRAPHIC ELEMENT
Expand Down
4 changes: 2 additions & 2 deletions node-graph/gcore/src/transform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::application_io::TextureFrameTable;
use crate::raster::bbox::AxisAlignedBbox;
use crate::raster::image::ImageFrameTable;
use crate::vector::VectorDataTable;
use crate::{Artboard, ArtboardGroup, CloneVarArgs, Color, Context, Ctx, ExtractAll, GraphicGroupTable, OwnedContextImpl};
use crate::{Artboard, ArtboardGroupTable, CloneVarArgs, Color, Context, Ctx, ExtractAll, GraphicGroupTable, OwnedContextImpl};

use glam::{DAffine2, DVec2};

Expand Down Expand Up @@ -132,7 +132,7 @@ impl From<()> for Footprint {
}

#[node_macro::node(category("Debug"))]
fn cull<T>(_: impl Ctx, #[implementations(VectorDataTable, GraphicGroupTable, Artboard, ImageFrameTable<Color>, ArtboardGroup)] data: T) -> T {
fn cull<T>(_: impl Ctx, #[implementations(VectorDataTable, GraphicGroupTable, Artboard, ImageFrameTable<Color>, ArtboardGroupTable)] data: T) -> T {
data
}

Expand Down
3 changes: 2 additions & 1 deletion node-graph/graph-craft/src/document/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ tagged_value! {
#[cfg_attr(feature = "serde", serde(deserialize_with = "graphene_core::migrate_graphic_group"))]
GraphicGroup(graphene_core::GraphicGroupTable),
GraphicElement(graphene_core::GraphicElement),
ArtboardGroup(graphene_core::ArtboardGroup),
#[cfg_attr(feature = "serde", serde(deserialize_with = "graphene_core::migrate_artboard_group"))] // TODO: Eventually remove this migration document upgrade code
ArtboardGroup(graphene_core::ArtboardGroupTable),
Curve(graphene_core::raster::curve::Curve),
Footprint(graphene_core::transform::Footprint),
Palette(Vec<Color>),
Expand Down
2 changes: 1 addition & 1 deletion node-graph/gstd/src/wasm_application_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ async fn render<'a: 'n, T: 'n + GraphicElementRendered + WasmNotSend>(
Context -> ImageFrameTable<Color>,
Context -> GraphicGroupTable,
Context -> graphene_core::Artboard,
Context -> graphene_core::ArtboardGroup,
Context -> graphene_core::ArtboardGroupTable,
Context -> Option<Color>,
Context -> Vec<Color>,
Context -> bool,
Expand Down

0 comments on commit fdab39a

Please sign in to comment.