mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-30 14:58:11 +08:00
Clean up 'Image' node by removing old 'Cull' node in sub-network (#2643)
* Clean up 'Image' node by removing old 'Cull' node in sub-network * Fix gamma correction on Decode Image node
This commit is contained in:
@@ -473,7 +473,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
|||||||
node_template: NodeTemplate {
|
node_template: NodeTemplate {
|
||||||
document_node: DocumentNode {
|
document_node: DocumentNode {
|
||||||
implementation: DocumentNodeImplementation::Network(NodeNetwork {
|
implementation: DocumentNodeImplementation::Network(NodeNetwork {
|
||||||
exports: vec![NodeInput::node(NodeId(2), 0)],
|
exports: vec![NodeInput::node(NodeId(1), 0)],
|
||||||
nodes: [
|
nodes: [
|
||||||
DocumentNode {
|
DocumentNode {
|
||||||
inputs: vec![NodeInput::value(TaggedValue::None, false), NodeInput::scope("editor-api"), NodeInput::network(concrete!(String), 1)],
|
inputs: vec![NodeInput::value(TaggedValue::None, false), NodeInput::scope("editor-api"), NodeInput::network(concrete!(String), 1)],
|
||||||
@@ -487,12 +487,6 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
|||||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_std::wasm_application_io::DecodeImageNode")),
|
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_std::wasm_application_io::DecodeImageNode")),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
DocumentNode {
|
|
||||||
inputs: vec![NodeInput::node(NodeId(1), 0)],
|
|
||||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::transform::CullNode")),
|
|
||||||
manual_composition: Some(concrete!(Context)),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
@@ -525,14 +519,6 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
|||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
DocumentNodeMetadata {
|
|
||||||
persistent_metadata: DocumentNodePersistentMetadata {
|
|
||||||
display_name: "Cull".to_string(),
|
|
||||||
node_type_metadata: NodeTypePersistentMetadata::node(IVec2::new(14, 0)),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
]
|
]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
@@ -845,41 +831,13 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
|||||||
PropertiesRow::with_override("Cellular Jitter", "TODO", WidgetOverride::Custom("noise_properties_cellular_jitter".to_string())),
|
PropertiesRow::with_override("Cellular Jitter", "TODO", WidgetOverride::Custom("noise_properties_cellular_jitter".to_string())),
|
||||||
],
|
],
|
||||||
output_names: vec!["Image".to_string()],
|
output_names: vec!["Image".to_string()],
|
||||||
network_metadata: Some(NodeNetworkMetadata {
|
|
||||||
persistent_metadata: NodeNetworkPersistentMetadata {
|
|
||||||
node_metadata: [
|
|
||||||
DocumentNodeMetadata {
|
|
||||||
persistent_metadata: DocumentNodePersistentMetadata {
|
|
||||||
display_name: "Noise Pattern".to_string(),
|
|
||||||
node_type_metadata: NodeTypePersistentMetadata::node(IVec2::new(0, 0)),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
DocumentNodeMetadata {
|
|
||||||
persistent_metadata: DocumentNodePersistentMetadata {
|
|
||||||
display_name: "Cull".to_string(),
|
|
||||||
node_type_metadata: NodeTypePersistentMetadata::node(IVec2::new(0, 0)),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
]
|
|
||||||
.into_iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(id, node)| (NodeId(id as u64), node))
|
|
||||||
.collect(),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
..Default::default()
|
|
||||||
}),
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
description: Cow::Borrowed("Generates different noise patterns."),
|
description: Cow::Borrowed("Generates different noise patterns."),
|
||||||
properties: None,
|
properties: None,
|
||||||
},
|
},
|
||||||
// TODO: This needs to work with resolution-aware (raster with footprint, post-Cull node) data.
|
// TODO: This needs to work with resolution-aware data.
|
||||||
// TODO: Auto-generate this from its proto node macro
|
// TODO: Auto-generate this from its proto node macro
|
||||||
DocumentNodeDefinition {
|
DocumentNodeDefinition {
|
||||||
identifier: "Mask",
|
identifier: "Mask",
|
||||||
@@ -906,7 +864,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
|||||||
description: Cow::Borrowed("TODO"),
|
description: Cow::Borrowed("TODO"),
|
||||||
properties: None,
|
properties: None,
|
||||||
},
|
},
|
||||||
// TODO: This needs to work with resolution-aware (raster with footprint, post-Cull node) data.
|
// TODO: This needs to work with resolution-aware data.
|
||||||
// TODO: Auto-generate this from its proto node macro
|
// TODO: Auto-generate this from its proto node macro
|
||||||
DocumentNodeDefinition {
|
DocumentNodeDefinition {
|
||||||
identifier: "Insert Channel",
|
identifier: "Insert Channel",
|
||||||
@@ -934,7 +892,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
|||||||
description: Cow::Borrowed("TODO"),
|
description: Cow::Borrowed("TODO"),
|
||||||
properties: None,
|
properties: None,
|
||||||
},
|
},
|
||||||
// TODO: This needs to work with resolution-aware (raster with footprint, post-Cull node) data.
|
// TODO: This needs to work with resolution-aware data.
|
||||||
DocumentNodeDefinition {
|
DocumentNodeDefinition {
|
||||||
identifier: "Combine Channels",
|
identifier: "Combine Channels",
|
||||||
category: "Raster",
|
category: "Raster",
|
||||||
@@ -1244,58 +1202,6 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
|
|||||||
description: Cow::Borrowed("TODO"),
|
description: Cow::Borrowed("TODO"),
|
||||||
properties: None,
|
properties: None,
|
||||||
},
|
},
|
||||||
DocumentNodeDefinition {
|
|
||||||
identifier: "Image",
|
|
||||||
category: "Raster",
|
|
||||||
node_template: NodeTemplate {
|
|
||||||
document_node: DocumentNode {
|
|
||||||
implementation: DocumentNodeImplementation::Network(NodeNetwork {
|
|
||||||
exports: vec![NodeInput::node(NodeId(0), 0)],
|
|
||||||
nodes: vec![DocumentNode {
|
|
||||||
inputs: vec![NodeInput::network(concrete!(ImageFrameTable<Color>), 1)],
|
|
||||||
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::transform::CullNode")),
|
|
||||||
manual_composition: Some(concrete!(Context)),
|
|
||||||
..Default::default()
|
|
||||||
}]
|
|
||||||
.into_iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(id, node)| (NodeId(id as u64), node))
|
|
||||||
.collect(),
|
|
||||||
..Default::default()
|
|
||||||
}),
|
|
||||||
inputs: vec![
|
|
||||||
NodeInput::value(TaggedValue::None, false),
|
|
||||||
NodeInput::value(TaggedValue::ImageFrame(ImageFrameTable::one_empty_image()), false),
|
|
||||||
],
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
persistent_node_metadata: DocumentNodePersistentMetadata {
|
|
||||||
input_properties: vec![("Empty", "TODO").into(), ("Image", "TODO").into()],
|
|
||||||
output_names: vec!["Image".to_string()],
|
|
||||||
network_metadata: Some(NodeNetworkMetadata {
|
|
||||||
persistent_metadata: NodeNetworkPersistentMetadata {
|
|
||||||
node_metadata: [DocumentNodeMetadata {
|
|
||||||
persistent_metadata: DocumentNodePersistentMetadata {
|
|
||||||
display_name: "Cull".to_string(),
|
|
||||||
node_type_metadata: NodeTypePersistentMetadata::node(IVec2::new(0, 0)),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
..Default::default()
|
|
||||||
}]
|
|
||||||
.into_iter()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(id, node)| (NodeId(id as u64), node))
|
|
||||||
.collect(),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
..Default::default()
|
|
||||||
}),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
},
|
|
||||||
description: Cow::Borrowed("TODO"),
|
|
||||||
properties: None,
|
|
||||||
},
|
|
||||||
#[cfg(feature = "gpu")]
|
#[cfg(feature = "gpu")]
|
||||||
DocumentNodeDefinition {
|
DocumentNodeDefinition {
|
||||||
identifier: "Uniform",
|
identifier: "Uniform",
|
||||||
|
|||||||
@@ -461,7 +461,7 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const REPLACEMENTS: [(&str, &str); 34] = [
|
const REPLACEMENTS: [(&str, &str); 35] = [
|
||||||
("graphene_core::AddArtboardNode", "graphene_core::graphic_element::AppendArtboardNode"),
|
("graphene_core::AddArtboardNode", "graphene_core::graphic_element::AppendArtboardNode"),
|
||||||
("graphene_core::ConstructArtboardNode", "graphene_core::graphic_element::ToArtboardNode"),
|
("graphene_core::ConstructArtboardNode", "graphene_core::graphic_element::ToArtboardNode"),
|
||||||
("graphene_core::ToGraphicElementNode", "graphene_core::graphic_element::ToElementNode"),
|
("graphene_core::ToGraphicElementNode", "graphene_core::graphic_element::ToElementNode"),
|
||||||
@@ -500,6 +500,7 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
|
|||||||
("graphene_core::vector::generator_nodes::StarGenerator", "graphene_core::vector::generator_nodes::StarNode"),
|
("graphene_core::vector::generator_nodes::StarGenerator", "graphene_core::vector::generator_nodes::StarNode"),
|
||||||
("graphene_std::executor::BlendGpuImageNode", "graphene_std::gpu_nodes::BlendGpuImageNode"),
|
("graphene_std::executor::BlendGpuImageNode", "graphene_std::gpu_nodes::BlendGpuImageNode"),
|
||||||
("graphene_std::raster::SampleNode", "graphene_std::raster::SampleImageNode"),
|
("graphene_std::raster::SampleNode", "graphene_std::raster::SampleImageNode"),
|
||||||
|
("graphene_core::transform::CullNode", "graphene_core::ops::IdentityNode"),
|
||||||
];
|
];
|
||||||
let mut network = document.network_interface.document_network().clone();
|
let mut network = document.network_interface.document_network().clone();
|
||||||
network.generate_node_paths(&[]);
|
network.generate_node_paths(&[]);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use crate::instances::Instances;
|
|||||||
use crate::raster::bbox::AxisAlignedBbox;
|
use crate::raster::bbox::AxisAlignedBbox;
|
||||||
use crate::raster::image::ImageFrameTable;
|
use crate::raster::image::ImageFrameTable;
|
||||||
use crate::vector::VectorDataTable;
|
use crate::vector::VectorDataTable;
|
||||||
use crate::{Artboard, ArtboardGroupTable, CloneVarArgs, Color, Context, Ctx, ExtractAll, GraphicGroupTable, OwnedContextImpl};
|
use crate::{Artboard, CloneVarArgs, Color, Context, Ctx, ExtractAll, GraphicGroupTable, OwnedContextImpl};
|
||||||
use core::f64;
|
use core::f64;
|
||||||
use glam::{DAffine2, DMat2, DVec2};
|
use glam::{DAffine2, DMat2, DVec2};
|
||||||
|
|
||||||
@@ -137,11 +137,6 @@ impl From<()> for Footprint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[node_macro::node(category("Debug"))]
|
|
||||||
fn cull<T>(_: impl Ctx, #[implementations(VectorDataTable, GraphicGroupTable, Artboard, ImageFrameTable<Color>, ArtboardGroupTable)] data: T) -> T {
|
|
||||||
data
|
|
||||||
}
|
|
||||||
|
|
||||||
impl core::hash::Hash for Footprint {
|
impl core::hash::Hash for Footprint {
|
||||||
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
|
||||||
self.transform.to_cols_array().iter().for_each(|x| x.to_le_bytes().hash(state));
|
self.transform.to_cols_array().iter().for_each(|x| x.to_le_bytes().hash(state));
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ use std::marker::PhantomData;
|
|||||||
#[derive(Debug, DynAny)]
|
#[derive(Debug, DynAny)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
IO(std::io::Error),
|
IO(std::io::Error),
|
||||||
Image(image::ImageError),
|
Image(::image::ImageError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<std::io::Error> for Error {
|
impl From<std::io::Error> for Error {
|
||||||
@@ -49,9 +49,9 @@ fn sample_image(ctx: impl ExtractFootprint + Clone + Send, image_frame: ImageFra
|
|||||||
return ImageFrameTable::one_empty_image();
|
return ImageFrameTable::one_empty_image();
|
||||||
}
|
}
|
||||||
|
|
||||||
let image_buffer = image::Rgba32FImage::from_raw(image.width, image.height, data).expect("Failed to convert internal image format into image-rs data type.");
|
let image_buffer = ::image::Rgba32FImage::from_raw(image.width, image.height, data).expect("Failed to convert internal image format into image-rs data type.");
|
||||||
|
|
||||||
let dynamic_image: image::DynamicImage = image_buffer.into();
|
let dynamic_image: ::image::DynamicImage = image_buffer.into();
|
||||||
let offset = (intersection.start - image_bounds.start).max(DVec2::ZERO);
|
let offset = (intersection.start - image_bounds.start).max(DVec2::ZERO);
|
||||||
let offset_px = image_size.transform_vector2(offset).as_uvec2();
|
let offset_px = image_size.transform_vector2(offset).as_uvec2();
|
||||||
let cropped = dynamic_image.crop_imm(offset_px.x, offset_px.y, size_px.x, size_px.y);
|
let cropped = dynamic_image.crop_imm(offset_px.x, offset_px.y, size_px.x, size_px.y);
|
||||||
@@ -66,7 +66,7 @@ fn sample_image(ctx: impl ExtractFootprint + Clone + Send, image_frame: ImageFra
|
|||||||
new_width = viewport_resolution_x as u32;
|
new_width = viewport_resolution_x as u32;
|
||||||
new_height = viewport_resolution_y as u32;
|
new_height = viewport_resolution_y as u32;
|
||||||
// TODO: choose filter based on quality requirements
|
// TODO: choose filter based on quality requirements
|
||||||
cropped.resize_exact(new_width, new_height, image::imageops::Triangle)
|
cropped.resize_exact(new_width, new_height, ::image::imageops::Triangle)
|
||||||
} else {
|
} else {
|
||||||
cropped
|
cropped
|
||||||
};
|
};
|
||||||
@@ -375,6 +375,12 @@ fn empty_image(_: impl Ctx, transform: DAffine2, color: Color) -> ImageFrameTabl
|
|||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Constructs a raster image.
|
||||||
|
#[node_macro::node(category(""))]
|
||||||
|
fn image(_: impl Ctx, _primary: (), image: ImageFrameTable<Color>) -> ImageFrameTable<Color> {
|
||||||
|
image
|
||||||
|
}
|
||||||
|
|
||||||
// #[cfg(feature = "serde")]
|
// #[cfg(feature = "serde")]
|
||||||
// macro_rules! generate_imaginate_node {
|
// macro_rules! generate_imaginate_node {
|
||||||
// ($($val:ident: $t:ident: $o:ty,)*) => {
|
// ($($val:ident: $t:ident: $o:ty,)*) => {
|
||||||
|
|||||||
@@ -83,7 +83,10 @@ fn decode_image(_: impl Ctx, data: Arc<[u8]>) -> ImageFrameTable<Color> {
|
|||||||
};
|
};
|
||||||
let image = image.to_rgba32f();
|
let image = image.to_rgba32f();
|
||||||
let image = Image {
|
let image = Image {
|
||||||
data: image.chunks(4).map(|pixel| Color::from_unassociated_alpha(pixel[0], pixel[1], pixel[2], pixel[3])).collect(),
|
data: image
|
||||||
|
.chunks(4)
|
||||||
|
.map(|pixel| Color::from_unassociated_alpha(pixel[0], pixel[1], pixel[2], pixel[3]).to_linear_srgb())
|
||||||
|
.collect(),
|
||||||
width: image.width(),
|
width: image.width(),
|
||||||
height: image.height(),
|
height: image.height(),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|||||||
Reference in New Issue
Block a user