mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-19 02:48:12 +08:00
Make the node system use ImageFrame more extensively (#1055)
This commit is contained in:
@@ -32,7 +32,7 @@ use document_legacy::layers::style::{Fill, RenderData, ViewMode};
|
||||
use document_legacy::layers::text_layer::Font;
|
||||
use document_legacy::{DocumentError, DocumentResponse, LayerId, Operation as DocumentOperation};
|
||||
use graph_craft::document::NodeId;
|
||||
use graphene_core::raster::color::Color;
|
||||
use graphene_core::raster::{Color, ImageFrame};
|
||||
use graphene_std::vector::subpath::Subpath;
|
||||
|
||||
use glam::{DAffine2, DVec2};
|
||||
@@ -603,21 +603,37 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||
PasteImage { image, mouse } => {
|
||||
let image_size = DVec2::new(image.width as f64, image.height as f64);
|
||||
|
||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
||||
|
||||
let path = vec![generate_uuid()];
|
||||
let image_node_id = 100;
|
||||
let mut network = crate::messages::portfolio::document::node_graph::new_image_network(32, image_node_id);
|
||||
|
||||
let Some(image_node_type) = crate::messages::portfolio::document::node_graph::resolve_document_node_type("Image") else {
|
||||
warn!("Image node should be in registry");
|
||||
return;
|
||||
};
|
||||
|
||||
let path = vec![generate_uuid()];
|
||||
let image_node_id = 100;
|
||||
let mut network = crate::messages::portfolio::document::node_graph::new_image_network(32, image_node_id);
|
||||
|
||||
// Transform of parent folder
|
||||
let to_parent_folder = self.document_legacy.generate_transform_across_scope(&path[..path.len() - 1], None).unwrap_or_default();
|
||||
|
||||
// Align the layer with the mouse or center of viewport
|
||||
let viewport_location = mouse.map_or(ipp.viewport_bounds.center(), |pos| pos.into());
|
||||
let center_in_viewport = DAffine2::from_translation(viewport_location - ipp.viewport_bounds.top_left);
|
||||
let center_in_viewport_layerspace = to_parent_folder.inverse() * center_in_viewport;
|
||||
|
||||
// Make layer the size of the image
|
||||
let fit_image_size = DAffine2::from_scale_angle_translation(image_size, 0., image_size / -2.);
|
||||
|
||||
let transform = (center_in_viewport_layerspace * fit_image_size);
|
||||
|
||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
||||
|
||||
network.nodes.insert(
|
||||
image_node_id,
|
||||
image_node_type.to_document_node(
|
||||
[graph_craft::document::NodeInput::value(graph_craft::document::value::TaggedValue::Image(image), false)],
|
||||
[graph_craft::document::NodeInput::value(
|
||||
graph_craft::document::value::TaggedValue::ImageFrame(ImageFrame { image, transform }),
|
||||
false,
|
||||
)],
|
||||
graph_craft::document::DocumentNodeMetadata::position((20, 4)),
|
||||
),
|
||||
);
|
||||
@@ -638,19 +654,13 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||
.into(),
|
||||
);
|
||||
|
||||
// Transform of parent folder
|
||||
let to_parent_folder = self.document_legacy.generate_transform_across_scope(&path[..path.len() - 1], None).unwrap_or_default();
|
||||
|
||||
// Align the layer with the mouse or center of viewport
|
||||
let viewport_location = mouse.map_or(ipp.viewport_bounds.center(), |pos| pos.into());
|
||||
let center_in_viewport = DAffine2::from_translation(viewport_location - ipp.viewport_bounds.top_left);
|
||||
let center_in_viewport_layerspace = to_parent_folder.inverse() * center_in_viewport;
|
||||
|
||||
// Make layer the size of the image
|
||||
let fit_image_size = DAffine2::from_scale_angle_translation(image_size, 0., image_size / -2.);
|
||||
|
||||
let transform = (center_in_viewport_layerspace * fit_image_size).to_cols_array();
|
||||
responses.push_back(DocumentOperation::SetLayerTransform { path, transform }.into());
|
||||
responses.push_back(
|
||||
DocumentOperation::SetLayerTransform {
|
||||
path,
|
||||
transform: transform.to_cols_array(),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
|
||||
responses.push_back(DocumentMessage::NodeGraphFrameGenerate.into());
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ fn static_nodes() -> Vec<DocumentNodeType> {
|
||||
nodes: [
|
||||
DocumentNode {
|
||||
name: "Identity".to_string(),
|
||||
inputs: vec![NodeInput::Network(concrete!(Image))],
|
||||
inputs: vec![NodeInput::Network(concrete!(ImageFrame))],
|
||||
implementation: DocumentNodeImplementation::Unresolved(NodeIdentifier::new("graphene_core::ops::IdNode")),
|
||||
metadata: Default::default(),
|
||||
},
|
||||
@@ -154,13 +154,13 @@ fn static_nodes() -> Vec<DocumentNodeType> {
|
||||
DocumentInputType {
|
||||
name: "In",
|
||||
data_type: FrontendGraphDataType::General,
|
||||
default: NodeInput::Network(concrete!(Image)),
|
||||
default: NodeInput::Network(concrete!(ImageFrame)),
|
||||
},
|
||||
DocumentInputType::value("Transform", TaggedValue::DAffine2(DAffine2::IDENTITY), false),
|
||||
],
|
||||
outputs: vec![
|
||||
DocumentOutputType {
|
||||
name: "Image",
|
||||
name: "Image Frame",
|
||||
data_type: FrontendGraphDataType::Raster,
|
||||
},
|
||||
DocumentOutputType {
|
||||
@@ -585,8 +585,8 @@ pub static IMAGINATE_NODE: Lazy<DocumentNodeType> = Lazy::new(|| DocumentNodeTyp
|
||||
category: "Image Synthesis",
|
||||
identifier: NodeImplementation::proto("graphene_std::raster::ImaginateNode<_>"),
|
||||
inputs: vec![
|
||||
DocumentInputType::value("Input Image", TaggedValue::Image(Image::empty()), true),
|
||||
DocumentInputType::value("Transform", TaggedValue::DAffine2(DAffine2::IDENTITY), true),
|
||||
DocumentInputType::value("Input Image", TaggedValue::ImageFrame(ImageFrame::empty()), true),
|
||||
DocumentInputType::value("Transform", TaggedValue::DAffine2(DAffine2::IDENTITY), false),
|
||||
DocumentInputType::value("Seed", TaggedValue::F64(0.), false), // Remember to keep index used in `NodeGraphFrameImaginateRandom` updated with this entry's index
|
||||
DocumentInputType::value("Resolution", TaggedValue::OptionalDVec2(None), false),
|
||||
DocumentInputType::value("Samples", TaggedValue::F64(30.), false),
|
||||
@@ -674,10 +674,7 @@ pub fn new_image_network(output_offset: i32, output_node_id: NodeId) -> NodeNetw
|
||||
),
|
||||
resolve_document_node_type("Output")
|
||||
.expect("Output node does not exist")
|
||||
.to_document_node([NodeInput::node(2, 0)], DocumentNodeMetadata::position((output_offset + 8, 4))),
|
||||
resolve_document_node_type("Image Frame")
|
||||
.expect("Image frame node does not exist")
|
||||
.to_document_node([NodeInput::node(output_node_id, 0), NodeInput::node(0, 1)], DocumentNodeMetadata::position((output_offset, 4))),
|
||||
.to_document_node([NodeInput::node(output_node_id, 0)], DocumentNodeMetadata::position((output_offset + 8, 4))),
|
||||
]
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
|
||||
@@ -19,17 +19,8 @@ pub struct NodeGraphExecutor {
|
||||
}
|
||||
|
||||
impl NodeGraphExecutor {
|
||||
/// Sets the transform property on the input node
|
||||
fn set_input_transform(network: &mut NodeNetwork, transform: DAffine2) {
|
||||
let Some(input_node) = network.nodes.get_mut(&network.inputs[0]) else {
|
||||
return;
|
||||
};
|
||||
input_node.inputs[1] = NodeInput::value(TaggedValue::DAffine2(transform), false);
|
||||
}
|
||||
|
||||
/// Execute the network by flattening it and creating a borrow stack. Casts the output to the generic `T`.
|
||||
fn execute_network<T: dyn_any::StaticType>(&mut self, mut network: NodeNetwork, image_frame: ImageFrame) -> Result<T, String> {
|
||||
Self::set_input_transform(&mut network, image_frame.transform);
|
||||
network.duplicate_outputs(&mut generate_uuid);
|
||||
network.remove_dead_nodes();
|
||||
|
||||
@@ -49,7 +40,7 @@ impl NodeGraphExecutor {
|
||||
use dyn_any::IntoDynAny;
|
||||
use graph_craft::executor::Executor;
|
||||
|
||||
let boxed = self.executor.execute(image_frame.image.into_dyn()).map_err(|e| e.to_string())?;
|
||||
let boxed = self.executor.execute(image_frame.into_dyn()).map_err(|e| e.to_string())?;
|
||||
|
||||
dyn_any::downcast::<T>(boxed).map(|v| *v)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user