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 @@ -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 All @@ -571,7 +571,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
.collect(),
..Default::default()
}),
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true)],
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true)],
..Default::default()
},
persistent_node_metadata: DocumentNodePersistentMetadata {
Expand Down Expand Up @@ -809,8 +809,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
document_node: DocumentNode {
implementation: DocumentNodeImplementation::proto("graphene_std::raster::MaskImageNode"),
inputs: vec![
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true),
],
..Default::default()
},
Expand All @@ -832,8 +832,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
document_node: DocumentNode {
implementation: DocumentNodeImplementation::proto("graphene_std::raster::InsertChannelNode"),
inputs: vec![
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true),
NodeInput::value(TaggedValue::RedGreenBlue(RedGreenBlue::default()), false),
],
..Default::default()
Expand All @@ -856,10 +856,10 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
implementation: DocumentNodeImplementation::proto("graphene_std::raster::CombineChannelsNode"),
inputs: vec![
NodeInput::value(TaggedValue::None, false),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true),
],
..Default::default()
},
Expand Down Expand Up @@ -929,7 +929,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {

..Default::default()
}),
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true)],
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true)],
..Default::default()
},
persistent_node_metadata: DocumentNodePersistentMetadata {
Expand Down Expand Up @@ -1011,8 +1011,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
..Default::default()
}),
inputs: vec![
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true),
NodeInput::value(TaggedValue::BrushStrokes(Vec::new()), false),
NodeInput::value(TaggedValue::BrushCache(BrushCache::new_proto()), false),
],
Expand Down Expand Up @@ -1061,7 +1061,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
node_template: NodeTemplate {
document_node: DocumentNode {
implementation: DocumentNodeImplementation::proto("graphene_core::memo::MemoNode"),
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true)],
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true)],
manual_composition: Some(concrete!(Context)),
..Default::default()
},
Expand All @@ -1080,7 +1080,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
node_template: NodeTemplate {
document_node: DocumentNode {
implementation: DocumentNodeImplementation::proto("graphene_core::memo::ImpureMemoNode"),
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true)],
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true)],
manual_composition: Some(concrete!(Context)),
..Default::default()
},
Expand Down Expand Up @@ -1112,7 +1112,10 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
.collect(),
..Default::default()
}),
inputs: vec![NodeInput::value(TaggedValue::None, false), NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), false)],
inputs: vec![
NodeInput::value(TaggedValue::None, false),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), false),
],
..Default::default()
},
persistent_node_metadata: DocumentNodePersistentMetadata {
Expand Down Expand Up @@ -1825,7 +1828,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
.collect(),
..Default::default()
}),
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true)],
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true)],
..Default::default()
},
persistent_node_metadata: DocumentNodePersistentMetadata {
Expand Down Expand Up @@ -1881,7 +1884,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
document_node: DocumentNode {
implementation: DocumentNodeImplementation::proto("graphene_std::executor::MapGpuSingleImageNode"),
inputs: vec![
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true),
NodeInput::value(TaggedValue::DocumentNode(DocumentNode::default()), true),
],
..Default::default()
Expand Down Expand Up @@ -1923,7 +1926,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
document_node: DocumentNode {
implementation: DocumentNodeImplementation::proto("graphene_core::raster::BrightnessContrastNode"),
inputs: vec![
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true),
NodeInput::value(TaggedValue::F64(0.), false),
NodeInput::value(TaggedValue::F64(0.), false),
NodeInput::value(TaggedValue::Bool(false), false),
Expand Down Expand Up @@ -2799,7 +2802,7 @@ pub static IMAGINATE_NODE: Lazy<DocumentNodeDefinition> = Lazy::new(|| DocumentN
..Default::default()
}),
inputs: vec![
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), true),
NodeInput::scope("editor-api"),
NodeInput::value(TaggedValue::ImaginateController(Default::default()), false),
NodeInput::value(TaggedValue::F64(0.), false), // Remember to keep index used in `ImaginateRandom` updated with this entry's index
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
5 changes: 5 additions & 0 deletions node-graph/gcore/src/application_io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ impl TransformMut for SurfaceFrame {
}
}

#[cfg(feature = "dyn-any")]
unsafe impl StaticType for SurfaceFrame {
type Static = SurfaceFrame;
}
Expand Down Expand Up @@ -90,6 +91,7 @@ impl PartialEq for ImageTexture {
}
}

#[cfg(feature = "dyn-any")]
unsafe impl StaticType for ImageTexture {
type Static = ImageTexture;
}
Expand Down Expand Up @@ -128,6 +130,7 @@ impl<S: Size> Size for SurfaceHandle<S> {
}
}

#[cfg(feature = "dyn-any")]
unsafe impl<T: 'static> StaticType for SurfaceHandle<T> {
type Static = SurfaceHandle<T>;
}
Expand All @@ -138,6 +141,7 @@ pub struct SurfaceHandleFrame<Surface> {
pub transform: DAffine2,
}

#[cfg(feature = "dyn-any")]
unsafe impl<T: 'static> StaticType for SurfaceHandleFrame<T> {
type Static = SurfaceHandleFrame<T>;
}
Expand Down Expand Up @@ -317,6 +321,7 @@ impl<T> Debug for EditorApi<T> {
}
}

#[cfg(feature = "dyn-any")]
unsafe impl<T: StaticTypeSized> StaticType for EditorApi<T> {
type Static = EditorApi<T::Static>;
}
53 changes: 36 additions & 17 deletions node-graph/gcore/src/graphic_element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,12 @@ pub struct Artboard {
pub clip: bool,
}

impl Default for Artboard {
fn default() -> Self {
Self::new(IVec2::ZERO, IVec2::new(1920, 1080))
}
}

impl Artboard {
pub fn new(location: IVec2, dimensions: IVec2) -> Self {
Self {
Expand All @@ -251,23 +257,38 @@ impl Artboard {
}
}

/// Contains multiple artboards.
#[derive(Clone, Default, Debug, Hash, PartialEq, DynAny)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ArtboardGroup {
pub artboards: Vec<(Artboard, Option<NodeId>)>,
}
// 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;

impl ArtboardGroup {
pub fn new() -> Self {
Default::default()
#[derive(Clone, Default, Debug, Hash, PartialEq, DynAny)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ArtboardGroup {
pub artboards: Vec<(Artboard, Option<NodeId>)>,
}

fn append_artboard(&mut self, artboard: Artboard, node_id: Option<NodeId>) {
self.artboards.push((artboard, node_id));
#[derive(serde::Serialize, serde::Deserialize)]
#[serde(untagged)]
enum EitherFormat {
ArtboardGroup(ArtboardGroup),
ArtboardGroupTable(ArtboardGroupTable),
}

Ok(match EitherFormat::deserialize(deserializer)? {
EitherFormat::ArtboardGroup(artboard_group) => {
let mut table = ArtboardGroupTable::empty();
for (artboard, source_node_id) in artboard_group.artboards {
table.push(artboard);
*table.instances_mut().last().unwrap().source_node_id = source_node_id;
}
table
}
EitherFormat::ArtboardGroupTable(artboard_group_table) => artboard_group_table,
})
}

pub type ArtboardGroupTable = Instances<Artboard>;

#[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 +406,13 @@ 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;
// let foot = ctx.footprint();
// log::debug!("{:?}", foot);
async fn append_artboard(_ctx: impl Ctx, mut artboards: ArtboardGroupTable, artboard: Artboard, node_path: Vec<NodeId>) -> ArtboardGroupTable {
// 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);

artboards.push(artboard);
*artboards.instances_mut().last().unwrap().source_node_id = encapsulating_node_id;

artboards
}
Expand Down
24 changes: 12 additions & 12 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,38 @@ 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 {
artboard.render_svg(render, render_params);
for artboard in self.instances() {
artboard.instance.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.instances().filter_map(|instance| instance.instance.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 {
artboard.collect_metadata(metadata, footprint, *element_id);
for instance in self.instances() {
instance.instance.collect_metadata(metadata, footprint, *instance.source_node_id);
}
}

fn add_upstream_click_targets(&self, click_targets: &mut Vec<ClickTarget>) {
for (artboard, _) in &self.artboards {
artboard.add_upstream_click_targets(click_targets);
for instance in self.instances() {
instance.instance.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 {
artboard.render_to_vello(scene, transform, context)
for instance in self.instances() {
instance.instance.render_to_vello(scene, transform, context)
}
}

fn contains_artboard(&self) -> bool {
!self.artboards.is_empty()
self.instances().count() > 0
}
}

Expand Down
Loading