Instance tables refactor part 2: move the transform and alpha_blending fields up a level (#2249)

* Fix domain data structure field plural naming

* Rename method one_item to one_instance

Rename method one_item to one_instance

* Move the Instance<T> methods over to providing an Instance<T>/InstanceMut<T>

Move the Instance<T> methods over to providing an Instance<T>/InstanceMut<T>

* Add transform and alpha_blending fields to Instances<T>

* Finish the refactor (Brush tool is broken though)

* Add test for brush node

* Fix brush node

* Fix default empty images being 1x1 instead of 0x0 as they should be

* Fix tests

* Fix path transform

* Add correct upgrading to move the transform/blending up a level

---------

Co-authored-by: hypercube <0hypercube@gmail.com>
This commit is contained in:
Keavon Chambers
2025-03-02 01:26:36 -08:00
parent 4ff2bdb04f
commit f1160e1ca6
33 changed files with 1099 additions and 984 deletions

View File

@@ -28,7 +28,7 @@ use crate::node_graph_executor::NodeGraphExecutor;
use bezier_rs::Subpath;
use graph_craft::document::value::TaggedValue;
use graph_craft::document::{NodeId, NodeInput, NodeNetwork, OldNodeNetwork};
use graphene_core::raster::image::ImageFrame;
use graphene_core::raster::image::{ImageFrame, ImageFrameTable};
use graphene_core::raster::BlendMode;
use graphene_core::vector::style::ViewMode;
use graphene_std::renderer::{ClickTarget, Quad};
@@ -818,12 +818,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageData<'_>> for DocumentMessag
responses.add(DocumentMessage::AddTransaction);
let image_frame = ImageFrame {
image,
transform: DAffine2::IDENTITY,
alpha_blending: Default::default(),
};
let layer = graph_modification_utils::new_image_layer(image_frame, layer_node_id, self.new_layer_parent(true), responses);
let layer = graph_modification_utils::new_image_layer(ImageFrameTable::new(ImageFrame { image }), layer_node_id, self.new_layer_parent(true), responses);
if let Some(name) = name {
responses.add(NodeGraphMessage::SetDisplayName {

View File

@@ -5,7 +5,7 @@ use crate::messages::prelude::*;
use bezier_rs::Subpath;
use graph_craft::document::NodeId;
use graphene_core::raster::image::ImageFrame;
use graphene_core::raster::image::ImageFrameTable;
use graphene_core::raster::BlendMode;
use graphene_core::text::{Font, TypesettingConfig};
use graphene_core::vector::brush_stroke::BrushStroke;
@@ -68,7 +68,7 @@ pub enum GraphOperationMessage {
},
NewBitmapLayer {
id: NodeId,
image_frame: ImageFrame<Color>,
image_frame: ImageFrameTable<Color>,
parent: LayerNodeIdentifier,
insert_index: usize,
},

View File

@@ -8,7 +8,7 @@ use bezier_rs::Subpath;
use graph_craft::concrete;
use graph_craft::document::value::TaggedValue;
use graph_craft::document::{NodeId, NodeInput};
use graphene_core::raster::image::{ImageFrame, ImageFrameTable};
use graphene_core::raster::image::ImageFrameTable;
use graphene_core::raster::BlendMode;
use graphene_core::text::{Font, TypesettingConfig};
use graphene_core::vector::brush_stroke::BrushStroke;
@@ -212,12 +212,11 @@ impl<'a> ModifyInputsContext<'a> {
self.network_interface.move_node_to_chain_start(&stroke_id, layer, &[]);
}
pub fn insert_image_data(&mut self, image_frame: ImageFrame<Color>, layer: LayerNodeIdentifier) {
pub fn insert_image_data(&mut self, image_frame: ImageFrameTable<Color>, layer: LayerNodeIdentifier) {
let transform = resolve_document_node_type("Transform").expect("Transform node does not exist").default_node_template();
let image = resolve_document_node_type("Image").expect("Image node does not exist").node_template_input_override([
Some(NodeInput::value(TaggedValue::None, false)),
Some(NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::new(image_frame)), false)),
]);
let image = resolve_document_node_type("Image")
.expect("Image node does not exist")
.node_template_input_override([Some(NodeInput::value(TaggedValue::None, false)), Some(NodeInput::value(TaggedValue::ImageFrame(image_frame), false))]);
let image_id = NodeId::new();
self.network_interface.insert_node(image_id, image, &[]);

View File

@@ -571,7 +571,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
.collect(),
..Default::default()
}),
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true)],
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true)],
..Default::default()
},
persistent_node_metadata: DocumentNodePersistentMetadata {
@@ -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::default()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
],
..Default::default()
},
@@ -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::default()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::RedGreenBlue(RedGreenBlue::default()), false),
],
..Default::default()
@@ -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::default()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), 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::empty()), true),
],
..Default::default()
},
@@ -929,7 +929,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
..Default::default()
}),
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true)],
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true)],
..Default::default()
},
persistent_node_metadata: DocumentNodePersistentMetadata {
@@ -1011,8 +1011,8 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
..Default::default()
}),
inputs: vec![
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::BrushStrokes(Vec::new()), false),
NodeInput::value(TaggedValue::BrushCache(BrushCache::new_proto()), false),
],
@@ -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::default()), true)],
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true)],
manual_composition: Some(concrete!(Context)),
..Default::default()
},
@@ -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::default()), true)],
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true)],
manual_composition: Some(concrete!(Context)),
..Default::default()
},
@@ -1112,7 +1112,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
.collect(),
..Default::default()
}),
inputs: vec![NodeInput::value(TaggedValue::None, false), NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), false)],
inputs: vec![NodeInput::value(TaggedValue::None, false), NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), false)],
..Default::default()
},
persistent_node_metadata: DocumentNodePersistentMetadata {
@@ -1825,7 +1825,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
.collect(),
..Default::default()
}),
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true)],
inputs: vec![NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true)],
..Default::default()
},
persistent_node_metadata: DocumentNodePersistentMetadata {
@@ -1881,7 +1881,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
document_node: DocumentNode {
implementation: DocumentNodeImplementation::proto("graphene_std::executor::MapGpuSingleImageNode"),
inputs: vec![
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::DocumentNode(DocumentNode::default()), true),
],
..Default::default()
@@ -1923,7 +1923,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
document_node: DocumentNode {
implementation: DocumentNodeImplementation::proto("graphene_core::raster::BrightnessContrastNode"),
inputs: vec![
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
NodeInput::value(TaggedValue::F64(0.), false),
NodeInput::value(TaggedValue::F64(0.), false),
NodeInput::value(TaggedValue::Bool(false), false),
@@ -1955,7 +1955,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
// document_node: DocumentNode {
// implementation: DocumentNodeImplementation::proto("graphene_core::raster::CurvesNode"),
// inputs: vec![
// NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
// NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), true),
// NodeInput::value(TaggedValue::Curve(Default::default()), false),
// ],
// ..Default::default()
@@ -2799,7 +2799,7 @@ pub static IMAGINATE_NODE: Lazy<DocumentNodeDefinition> = Lazy::new(|| DocumentN
..Default::default()
}),
inputs: vec![
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::default()), true),
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::empty()), 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

View File

@@ -457,7 +457,7 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
}
};
const REPLACEMENTS: [(&str, &str); 35] = [
const REPLACEMENTS: [(&str, &str); 34] = [
("graphene_core::AddArtboardNode", "graphene_core::graphic_element::AppendArtboardNode"),
("graphene_core::ConstructArtboardNode", "graphene_core::graphic_element::ToArtboardNode"),
("graphene_core::ToGraphicElementNode", "graphene_core::graphic_element::ToElementNode"),
@@ -488,7 +488,6 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
("graphene_core::vector::SplinesFromPointsNode", "graphene_core::vector::SplineNode"),
("graphene_core::vector::generator_nodes::EllipseGenerator", "graphene_core::vector::generator_nodes::EllipseNode"),
("graphene_core::vector::generator_nodes::LineGenerator", "graphene_core::vector::generator_nodes::LineNode"),
("graphene_core::vector::generator_nodes::PathGenerator", "graphene_core::vector::generator_nodes::PathNode"),
("graphene_core::vector::generator_nodes::RectangleGenerator", "graphene_core::vector::generator_nodes::RectangleNode"),
(
"graphene_core::vector::generator_nodes::RegularPolygonGenerator",

View File

@@ -6,7 +6,7 @@ use crate::messages::prelude::*;
use bezier_rs::Subpath;
use graph_craft::document::{value::TaggedValue, NodeId, NodeInput};
use graphene_core::raster::image::ImageFrame;
use graphene_core::raster::image::ImageFrameTable;
use graphene_core::raster::BlendMode;
use graphene_core::text::{Font, TypesettingConfig};
use graphene_core::vector::style::Gradient;
@@ -207,7 +207,7 @@ pub fn new_vector_layer(subpaths: Vec<Subpath<PointId>>, id: NodeId, parent: Lay
}
/// Create a new bitmap layer.
pub fn new_image_layer(image_frame: ImageFrame<Color>, id: NodeId, parent: LayerNodeIdentifier, responses: &mut VecDeque<Message>) -> LayerNodeIdentifier {
pub fn new_image_layer(image_frame: ImageFrameTable<Color>, id: NodeId, parent: LayerNodeIdentifier, responses: &mut VecDeque<Message>) -> LayerNodeIdentifier {
let insert_index = 0;
responses.add(GraphOperationMessage::NewBitmapLayer {
id,

View File

@@ -298,9 +298,9 @@ impl NodeRuntime {
}
// Insert the vector modify if we are dealing with vector data
else if let Some(record) = introspected_data.downcast_ref::<IORecord<Context, VectorDataTable>>() {
self.vector_modify.insert(parent_network_node_id, record.output.one_item().clone());
self.vector_modify.insert(parent_network_node_id, record.output.one_instance().instance.clone());
} else if let Some(record) = introspected_data.downcast_ref::<IORecord<(), VectorDataTable>>() {
self.vector_modify.insert(parent_network_node_id, record.output.one_item().clone());
self.vector_modify.insert(parent_network_node_id, record.output.one_instance().instance.clone());
}
}
}