mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-27 10:08:12 +08:00
move nodes from graphic_element itself to gelement-nodes
This commit is contained in:
@@ -242,14 +242,14 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
|||||||
// Secondary (left) input type coercion
|
// Secondary (left) input type coercion
|
||||||
DocumentNode {
|
DocumentNode {
|
||||||
inputs: vec![NodeInput::network(generic!(T), 1)],
|
inputs: vec![NodeInput::network(generic!(T), 1)],
|
||||||
implementation: DocumentNodeImplementation::proto("graphene_core::graphic_element::ToElementNode"),
|
implementation: DocumentNodeImplementation::proto("graphene_element_nodes::conversion::ToElementNode"),
|
||||||
manual_composition: Some(concrete!(Context)),
|
manual_composition: Some(concrete!(Context)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
// Primary (bottom) input type coercion
|
// Primary (bottom) input type coercion
|
||||||
DocumentNode {
|
DocumentNode {
|
||||||
inputs: vec![NodeInput::network(generic!(T), 0)],
|
inputs: vec![NodeInput::network(generic!(T), 0)],
|
||||||
implementation: DocumentNodeImplementation::proto("graphene_core::graphic_element::ToGroupNode"),
|
implementation: DocumentNodeImplementation::proto("graphene_element_nodes::conversion::ToGroupNode"),
|
||||||
manual_composition: Some(concrete!(Context)),
|
manual_composition: Some(concrete!(Context)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
@@ -268,7 +268,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
|||||||
NodeInput::node(NodeId(2), 0),
|
NodeInput::node(NodeId(2), 0),
|
||||||
NodeInput::Reflection(graph_craft::document::DocumentNodeMetadata::DocumentNodePath),
|
NodeInput::Reflection(graph_craft::document::DocumentNodeMetadata::DocumentNodePath),
|
||||||
],
|
],
|
||||||
implementation: DocumentNodeImplementation::proto("graphene_core::graphic_element::LayerNode"),
|
implementation: DocumentNodeImplementation::proto("graphene_element_nodes::conversion::LayerNode"),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@@ -349,7 +349,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
|||||||
// Ensure this ID is kept in sync with the ID in set_alias so that the name input is kept in sync with the alias
|
// Ensure this ID is kept in sync with the ID in set_alias so that the name input is kept in sync with the alias
|
||||||
DocumentNode {
|
DocumentNode {
|
||||||
manual_composition: Some(generic!(T)),
|
manual_composition: Some(generic!(T)),
|
||||||
implementation: DocumentNodeImplementation::proto("graphene_core::graphic_element::ToArtboardNode"),
|
implementation: DocumentNodeImplementation::proto("graphene_element_nodes::conversion::ToArtboardNode"),
|
||||||
inputs: vec![
|
inputs: vec![
|
||||||
NodeInput::network(concrete!(TaggedValue), 1),
|
NodeInput::network(concrete!(TaggedValue), 1),
|
||||||
NodeInput::value(TaggedValue::String(String::from("Artboard")), false),
|
NodeInput::value(TaggedValue::String(String::from("Artboard")), false),
|
||||||
@@ -376,7 +376,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
|||||||
NodeInput::node(NodeId(1), 0),
|
NodeInput::node(NodeId(1), 0),
|
||||||
NodeInput::Reflection(graph_craft::document::DocumentNodeMetadata::DocumentNodePath),
|
NodeInput::Reflection(graph_craft::document::DocumentNodeMetadata::DocumentNodePath),
|
||||||
],
|
],
|
||||||
implementation: DocumentNodeImplementation::proto("graphene_core::graphic_element::AppendArtboardNode"),
|
implementation: DocumentNodeImplementation::proto("graphene_element_nodes::conversion::AppendArtboardNode"),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -131,6 +131,13 @@ const REPLACEMENTS: &[(&str, &str)] = &[
|
|||||||
("graphene_std::raster::MaskImageNode", "graphene_std::raster::MaskNode"),
|
("graphene_std::raster::MaskImageNode", "graphene_std::raster::MaskNode"),
|
||||||
("graphene_core::vector::FlattenVectorElementsNode", "graphene_core::vector::FlattenPathNode"),
|
("graphene_core::vector::FlattenVectorElementsNode", "graphene_core::vector::FlattenPathNode"),
|
||||||
("graphene_std::vector::BooleanOperationNode", "graphene_path_bool::BooleanOperationNode"),
|
("graphene_std::vector::BooleanOperationNode", "graphene_path_bool::BooleanOperationNode"),
|
||||||
|
("graphene_core::graphic_element::LayerNode", "graphene_element_nodes::conversion::LayerNode"),
|
||||||
|
("graphene_core::graphic_element::ToElementNode", "graphene_element_nodes::conversion::ToElementNode"),
|
||||||
|
("graphene_core::graphic_element::ToGroupNode", "graphene_element_nodes::conversion::ToGroupNode"),
|
||||||
|
("graphene_core::graphic_element::FlattenGroupNode", "graphene_element_nodes::conversion::FlattenGroupNode"),
|
||||||
|
("graphene_core::graphic_element::FlattenVectorNode", "graphene_element_nodes::conversion::FlattenVectorNode"),
|
||||||
|
("graphene_core::graphic_element::ToArtboardNode", "graphene_element_nodes::conversion::ToArtboardNode"),
|
||||||
|
("graphene_core::graphic_element::AppendArtboardNode", "graphene_element_nodes::conversion::AppendArtboardNode"),
|
||||||
];
|
];
|
||||||
|
|
||||||
pub fn document_migration_string_preprocessing(document_serialized_content: String) -> String {
|
pub fn document_migration_string_preprocessing(document_serialized_content: String) -> String {
|
||||||
|
|||||||
@@ -567,7 +567,9 @@ mod test_artboard {
|
|||||||
Ok(instrumented) => instrumented,
|
Ok(instrumented) => instrumented,
|
||||||
Err(e) => panic!("Failed to evaluate graph: {}", e),
|
Err(e) => panic!("Failed to evaluate graph: {}", e),
|
||||||
};
|
};
|
||||||
instrumented.grab_all_input::<graphene_std::append_artboard::ArtboardInput>(&editor.runtime).collect()
|
instrumented
|
||||||
|
.grab_all_input::<graphene_std::element_nodes::conversion::append_artboard::ArtboardInput>(&editor.runtime)
|
||||||
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
use crate::blending::AlphaBlending;
|
use crate::blending::AlphaBlending;
|
||||||
use crate::bounds::BoundingBox;
|
use crate::bounds::BoundingBox;
|
||||||
|
use crate::color::Color;
|
||||||
use crate::instances::{Instance, Instances};
|
use crate::instances::{Instance, Instances};
|
||||||
use crate::math::quad::Quad;
|
use crate::math::quad::Quad;
|
||||||
use crate::raster::image::Image;
|
use crate::raster::image::Image;
|
||||||
use crate::raster_types::{CPU, GPU, Raster, RasterDataTable};
|
use crate::raster_types::{CPU, GPU, Raster, RasterDataTable};
|
||||||
use crate::transform::TransformMut;
|
|
||||||
use crate::uuid::NodeId;
|
use crate::uuid::NodeId;
|
||||||
use crate::vector::{VectorData, VectorDataTable};
|
use crate::vector::{VectorData, VectorDataTable};
|
||||||
use crate::{CloneVarArgs, Color, Context, Ctx, ExtractAll, OwnedContextImpl};
|
|
||||||
use dyn_any::DynAny;
|
use dyn_any::DynAny;
|
||||||
use glam::{DAffine2, DVec2, IVec2};
|
use glam::{DAffine2, DVec2, IVec2};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
@@ -323,188 +322,6 @@ impl BoundingBox for ArtboardGroupTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[node_macro::node(category(""))]
|
|
||||||
async fn layer<I: 'n + Send + Clone>(
|
|
||||||
_: impl Ctx,
|
|
||||||
#[implementations(GraphicGroupTable, VectorDataTable, RasterDataTable<CPU>, RasterDataTable<GPU>)] mut stack: Instances<I>,
|
|
||||||
#[implementations(GraphicElement, VectorData, Raster<CPU>, Raster<GPU>)] element: I,
|
|
||||||
node_path: Vec<NodeId>,
|
|
||||||
) -> Instances<I> {
|
|
||||||
// Get the penultimate element of the node path, or None if the path is too short
|
|
||||||
let source_node_id = node_path.get(node_path.len().wrapping_sub(2)).copied();
|
|
||||||
|
|
||||||
stack.push(Instance {
|
|
||||||
instance: element,
|
|
||||||
transform: DAffine2::IDENTITY,
|
|
||||||
alpha_blending: AlphaBlending::default(),
|
|
||||||
source_node_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
stack
|
|
||||||
}
|
|
||||||
|
|
||||||
#[node_macro::node(category("Debug"))]
|
|
||||||
async fn to_element<Data: Into<GraphicElement> + 'n>(
|
|
||||||
_: impl Ctx,
|
|
||||||
#[implementations(
|
|
||||||
GraphicGroupTable,
|
|
||||||
VectorDataTable,
|
|
||||||
RasterDataTable<CPU>,
|
|
||||||
RasterDataTable<GPU>,
|
|
||||||
)]
|
|
||||||
data: Data,
|
|
||||||
) -> GraphicElement {
|
|
||||||
data.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[node_macro::node(category("General"))]
|
|
||||||
async fn to_group<Data: Into<GraphicGroupTable> + 'n>(
|
|
||||||
_: impl Ctx,
|
|
||||||
#[implementations(
|
|
||||||
GraphicGroupTable,
|
|
||||||
VectorDataTable,
|
|
||||||
RasterDataTable<CPU>,
|
|
||||||
RasterDataTable<GPU>,
|
|
||||||
)]
|
|
||||||
element: Data,
|
|
||||||
) -> GraphicGroupTable {
|
|
||||||
element.into()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[node_macro::node(category("General"))]
|
|
||||||
async fn flatten_group(_: impl Ctx, group: GraphicGroupTable, fully_flatten: bool) -> GraphicGroupTable {
|
|
||||||
// TODO: Avoid mutable reference, instead return a new GraphicGroupTable?
|
|
||||||
fn flatten_group(output_group_table: &mut GraphicGroupTable, current_group_table: GraphicGroupTable, fully_flatten: bool, recursion_depth: usize) {
|
|
||||||
for current_instance in current_group_table.instance_ref_iter() {
|
|
||||||
let current_element = current_instance.instance.clone();
|
|
||||||
let reference = *current_instance.source_node_id;
|
|
||||||
|
|
||||||
let recurse = fully_flatten || recursion_depth == 0;
|
|
||||||
|
|
||||||
match current_element {
|
|
||||||
// If we're allowed to recurse, flatten any GraphicGroups we encounter
|
|
||||||
GraphicElement::GraphicGroup(mut current_element) if recurse => {
|
|
||||||
// Apply the parent group's transform to all child elements
|
|
||||||
for graphic_element in current_element.instance_mut_iter() {
|
|
||||||
*graphic_element.transform = *current_instance.transform * *graphic_element.transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
flatten_group(output_group_table, current_element, fully_flatten, recursion_depth + 1);
|
|
||||||
}
|
|
||||||
// Handle any leaf elements we encounter, which can be either non-GraphicGroup elements or GraphicGroups that we don't want to flatten
|
|
||||||
_ => {
|
|
||||||
output_group_table.push(Instance {
|
|
||||||
instance: current_element,
|
|
||||||
transform: *current_instance.transform,
|
|
||||||
alpha_blending: *current_instance.alpha_blending,
|
|
||||||
source_node_id: reference,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut output = GraphicGroupTable::default();
|
|
||||||
flatten_group(&mut output, group, fully_flatten, 0);
|
|
||||||
|
|
||||||
output
|
|
||||||
}
|
|
||||||
|
|
||||||
#[node_macro::node(category("Vector"))]
|
|
||||||
async fn flatten_vector(_: impl Ctx, group: GraphicGroupTable) -> VectorDataTable {
|
|
||||||
// TODO: Avoid mutable reference, instead return a new GraphicGroupTable?
|
|
||||||
fn flatten_group(output_group_table: &mut VectorDataTable, current_group_table: GraphicGroupTable) {
|
|
||||||
for current_instance in current_group_table.instance_ref_iter() {
|
|
||||||
let current_element = current_instance.instance.clone();
|
|
||||||
let reference = *current_instance.source_node_id;
|
|
||||||
|
|
||||||
match current_element {
|
|
||||||
// If we're allowed to recurse, flatten any GraphicGroups we encounter
|
|
||||||
GraphicElement::GraphicGroup(mut current_element) => {
|
|
||||||
// Apply the parent group's transform to all child elements
|
|
||||||
for graphic_element in current_element.instance_mut_iter() {
|
|
||||||
*graphic_element.transform = *current_instance.transform * *graphic_element.transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
flatten_group(output_group_table, current_element);
|
|
||||||
}
|
|
||||||
// Handle any leaf elements we encounter, which can be either non-GraphicGroup elements or GraphicGroups that we don't want to flatten
|
|
||||||
GraphicElement::VectorData(vector_instance) => {
|
|
||||||
for current_element in vector_instance.instance_ref_iter() {
|
|
||||||
output_group_table.push(Instance {
|
|
||||||
instance: current_element.instance.clone(),
|
|
||||||
transform: *current_instance.transform * *current_element.transform,
|
|
||||||
alpha_blending: AlphaBlending {
|
|
||||||
blend_mode: current_element.alpha_blending.blend_mode,
|
|
||||||
opacity: current_instance.alpha_blending.opacity * current_element.alpha_blending.opacity,
|
|
||||||
fill: current_element.alpha_blending.fill,
|
|
||||||
clip: current_element.alpha_blending.clip,
|
|
||||||
},
|
|
||||||
source_node_id: reference,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut output = VectorDataTable::default();
|
|
||||||
flatten_group(&mut output, group);
|
|
||||||
|
|
||||||
output
|
|
||||||
}
|
|
||||||
|
|
||||||
#[node_macro::node(category(""))]
|
|
||||||
async fn to_artboard<Data: Into<GraphicGroupTable> + 'n>(
|
|
||||||
ctx: impl ExtractAll + CloneVarArgs + Ctx,
|
|
||||||
#[implementations(
|
|
||||||
Context -> GraphicGroupTable,
|
|
||||||
Context -> VectorDataTable,
|
|
||||||
Context -> RasterDataTable<CPU>,
|
|
||||||
Context -> RasterDataTable<GPU>,
|
|
||||||
)]
|
|
||||||
contents: impl Node<Context<'static>, Output = Data>,
|
|
||||||
label: String,
|
|
||||||
location: IVec2,
|
|
||||||
dimensions: IVec2,
|
|
||||||
background: Color,
|
|
||||||
clip: bool,
|
|
||||||
) -> Artboard {
|
|
||||||
let footprint = ctx.try_footprint().copied();
|
|
||||||
let mut new_ctx = OwnedContextImpl::from(ctx);
|
|
||||||
if let Some(mut footprint) = footprint {
|
|
||||||
footprint.translate(location.as_dvec2());
|
|
||||||
new_ctx = new_ctx.with_footprint(footprint);
|
|
||||||
}
|
|
||||||
let graphic_group = contents.eval(new_ctx.into_context()).await;
|
|
||||||
|
|
||||||
Artboard {
|
|
||||||
graphic_group: graphic_group.into(),
|
|
||||||
label,
|
|
||||||
location: location.min(location + dimensions),
|
|
||||||
dimensions: dimensions.abs(),
|
|
||||||
background,
|
|
||||||
clip,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[node_macro::node(category(""))]
|
|
||||||
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.push(Instance {
|
|
||||||
instance: artboard,
|
|
||||||
transform: DAffine2::IDENTITY,
|
|
||||||
alpha_blending: AlphaBlending::default(),
|
|
||||||
source_node_id: encapsulating_node_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
artboards
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Remove this one
|
// TODO: Remove this one
|
||||||
impl From<Image<Color>> for GraphicElement {
|
impl From<Image<Color>> for GraphicElement {
|
||||||
fn from(raster_data: Image<Color>) -> Self {
|
fn from(raster_data: Image<Color>) -> Self {
|
||||||
|
|||||||
@@ -0,0 +1,189 @@
|
|||||||
|
use glam::{DAffine2, IVec2};
|
||||||
|
use graphene_core::instances::{Instance, Instances};
|
||||||
|
use graphene_core::raster_types::{CPU, GPU, Raster, RasterDataTable};
|
||||||
|
use graphene_core::transform::TransformMut;
|
||||||
|
use graphene_core::uuid::NodeId;
|
||||||
|
use graphene_core::vector::{VectorData, VectorDataTable};
|
||||||
|
use graphene_core::{AlphaBlending, Artboard, ArtboardGroupTable, CloneVarArgs, Color, Context, Ctx, ExtractAll, GraphicElement, GraphicGroupTable, OwnedContextImpl};
|
||||||
|
|
||||||
|
#[node_macro::node(category(""))]
|
||||||
|
async fn layer<I: 'n + Send + Clone>(
|
||||||
|
_: impl Ctx,
|
||||||
|
#[implementations(GraphicGroupTable, VectorDataTable, RasterDataTable<CPU>, RasterDataTable<GPU>)] mut stack: Instances<I>,
|
||||||
|
#[implementations(GraphicElement, VectorData, Raster<CPU>, Raster<GPU>)] element: I,
|
||||||
|
node_path: Vec<NodeId>,
|
||||||
|
) -> Instances<I> {
|
||||||
|
// Get the penultimate element of the node path, or None if the path is too short
|
||||||
|
let source_node_id = node_path.get(node_path.len().wrapping_sub(2)).copied();
|
||||||
|
|
||||||
|
stack.push(Instance {
|
||||||
|
instance: element,
|
||||||
|
transform: DAffine2::IDENTITY,
|
||||||
|
alpha_blending: AlphaBlending::default(),
|
||||||
|
source_node_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
stack
|
||||||
|
}
|
||||||
|
|
||||||
|
#[node_macro::node(category("Debug"))]
|
||||||
|
async fn to_element<Data: Into<GraphicElement> + 'n>(
|
||||||
|
_: impl Ctx,
|
||||||
|
#[implementations(
|
||||||
|
GraphicGroupTable,
|
||||||
|
VectorDataTable,
|
||||||
|
RasterDataTable<CPU>,
|
||||||
|
RasterDataTable<GPU>,
|
||||||
|
)]
|
||||||
|
data: Data,
|
||||||
|
) -> GraphicElement {
|
||||||
|
data.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[node_macro::node(category("General"))]
|
||||||
|
async fn to_group<Data: Into<GraphicGroupTable> + 'n>(
|
||||||
|
_: impl Ctx,
|
||||||
|
#[implementations(
|
||||||
|
GraphicGroupTable,
|
||||||
|
VectorDataTable,
|
||||||
|
RasterDataTable<CPU>,
|
||||||
|
RasterDataTable<GPU>,
|
||||||
|
)]
|
||||||
|
element: Data,
|
||||||
|
) -> GraphicGroupTable {
|
||||||
|
element.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[node_macro::node(category("General"))]
|
||||||
|
async fn flatten_group(_: impl Ctx, group: GraphicGroupTable, fully_flatten: bool) -> GraphicGroupTable {
|
||||||
|
// TODO: Avoid mutable reference, instead return a new GraphicGroupTable?
|
||||||
|
fn flatten_group(output_group_table: &mut GraphicGroupTable, current_group_table: GraphicGroupTable, fully_flatten: bool, recursion_depth: usize) {
|
||||||
|
for current_instance in current_group_table.instance_ref_iter() {
|
||||||
|
let current_element = current_instance.instance.clone();
|
||||||
|
let reference = *current_instance.source_node_id;
|
||||||
|
|
||||||
|
let recurse = fully_flatten || recursion_depth == 0;
|
||||||
|
|
||||||
|
match current_element {
|
||||||
|
// If we're allowed to recurse, flatten any GraphicGroups we encounter
|
||||||
|
GraphicElement::GraphicGroup(mut current_element) if recurse => {
|
||||||
|
// Apply the parent group's transform to all child elements
|
||||||
|
for graphic_element in current_element.instance_mut_iter() {
|
||||||
|
*graphic_element.transform = *current_instance.transform * *graphic_element.transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatten_group(output_group_table, current_element, fully_flatten, recursion_depth + 1);
|
||||||
|
}
|
||||||
|
// Handle any leaf elements we encounter, which can be either non-GraphicGroup elements or GraphicGroups that we don't want to flatten
|
||||||
|
_ => {
|
||||||
|
output_group_table.push(Instance {
|
||||||
|
instance: current_element,
|
||||||
|
transform: *current_instance.transform,
|
||||||
|
alpha_blending: *current_instance.alpha_blending,
|
||||||
|
source_node_id: reference,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut output = GraphicGroupTable::default();
|
||||||
|
flatten_group(&mut output, group, fully_flatten, 0);
|
||||||
|
|
||||||
|
output
|
||||||
|
}
|
||||||
|
|
||||||
|
#[node_macro::node(category("Vector"))]
|
||||||
|
async fn flatten_vector(_: impl Ctx, group: GraphicGroupTable) -> VectorDataTable {
|
||||||
|
// TODO: Avoid mutable reference, instead return a new GraphicGroupTable?
|
||||||
|
fn flatten_group(output_group_table: &mut VectorDataTable, current_group_table: GraphicGroupTable) {
|
||||||
|
for current_instance in current_group_table.instance_ref_iter() {
|
||||||
|
let current_element = current_instance.instance.clone();
|
||||||
|
let reference = *current_instance.source_node_id;
|
||||||
|
|
||||||
|
match current_element {
|
||||||
|
// If we're allowed to recurse, flatten any GraphicGroups we encounter
|
||||||
|
GraphicElement::GraphicGroup(mut current_element) => {
|
||||||
|
// Apply the parent group's transform to all child elements
|
||||||
|
for graphic_element in current_element.instance_mut_iter() {
|
||||||
|
*graphic_element.transform = *current_instance.transform * *graphic_element.transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatten_group(output_group_table, current_element);
|
||||||
|
}
|
||||||
|
// Handle any leaf elements we encounter, which can be either non-GraphicGroup elements or GraphicGroups that we don't want to flatten
|
||||||
|
GraphicElement::VectorData(vector_instance) => {
|
||||||
|
for current_element in vector_instance.instance_ref_iter() {
|
||||||
|
output_group_table.push(Instance {
|
||||||
|
instance: current_element.instance.clone(),
|
||||||
|
transform: *current_instance.transform * *current_element.transform,
|
||||||
|
alpha_blending: AlphaBlending {
|
||||||
|
blend_mode: current_element.alpha_blending.blend_mode,
|
||||||
|
opacity: current_instance.alpha_blending.opacity * current_element.alpha_blending.opacity,
|
||||||
|
fill: current_element.alpha_blending.fill,
|
||||||
|
clip: current_element.alpha_blending.clip,
|
||||||
|
},
|
||||||
|
source_node_id: reference,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut output = VectorDataTable::default();
|
||||||
|
flatten_group(&mut output, group);
|
||||||
|
|
||||||
|
output
|
||||||
|
}
|
||||||
|
|
||||||
|
#[node_macro::node(category(""))]
|
||||||
|
async fn to_artboard<Data: Into<GraphicGroupTable> + 'n>(
|
||||||
|
ctx: impl ExtractAll + CloneVarArgs + Ctx,
|
||||||
|
#[implementations(
|
||||||
|
Context -> GraphicGroupTable,
|
||||||
|
Context -> VectorDataTable,
|
||||||
|
Context -> RasterDataTable<CPU>,
|
||||||
|
Context -> RasterDataTable<GPU>,
|
||||||
|
)]
|
||||||
|
contents: impl Node<Context<'static>, Output = Data>,
|
||||||
|
label: String,
|
||||||
|
location: IVec2,
|
||||||
|
dimensions: IVec2,
|
||||||
|
background: Color,
|
||||||
|
clip: bool,
|
||||||
|
) -> Artboard {
|
||||||
|
let footprint = ctx.try_footprint().copied();
|
||||||
|
let mut new_ctx = OwnedContextImpl::from(ctx);
|
||||||
|
if let Some(mut footprint) = footprint {
|
||||||
|
footprint.translate(location.as_dvec2());
|
||||||
|
new_ctx = new_ctx.with_footprint(footprint);
|
||||||
|
}
|
||||||
|
let graphic_group = contents.eval(new_ctx.into_context()).await;
|
||||||
|
|
||||||
|
Artboard {
|
||||||
|
graphic_group: graphic_group.into(),
|
||||||
|
label,
|
||||||
|
location: location.min(location + dimensions),
|
||||||
|
dimensions: dimensions.abs(),
|
||||||
|
background,
|
||||||
|
clip,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[node_macro::node(category(""))]
|
||||||
|
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.push(Instance {
|
||||||
|
instance: artboard,
|
||||||
|
transform: DAffine2::IDENTITY,
|
||||||
|
alpha_blending: AlphaBlending::default(),
|
||||||
|
source_node_id: encapsulating_node_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
artboards
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
pub mod animation;
|
pub mod animation;
|
||||||
pub mod blending_nodes;
|
pub mod blending_nodes;
|
||||||
|
pub mod conversion;
|
||||||
pub mod instance;
|
pub mod instance;
|
||||||
pub mod logic;
|
pub mod logic;
|
||||||
pub mod transform_nodes;
|
pub mod transform_nodes;
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ pub mod wasm_application_io;
|
|||||||
pub use graphene_application_io as application_io;
|
pub use graphene_application_io as application_io;
|
||||||
pub use graphene_core::vector;
|
pub use graphene_core::vector;
|
||||||
pub use graphene_core::*;
|
pub use graphene_core::*;
|
||||||
|
pub use graphene_element_nodes as element_nodes;
|
||||||
pub use graphene_element_nodes::animation;
|
pub use graphene_element_nodes::animation;
|
||||||
pub use graphene_math_nodes as math_nodes;
|
pub use graphene_math_nodes as math_nodes;
|
||||||
pub use graphene_path_bool as path_bool;
|
pub use graphene_path_bool as path_bool;
|
||||||
|
|||||||
Reference in New Issue
Block a user