Node network subgraph editing (#1750)

* Breadcrumb visualization, nested network consistency, create definitions for Merge internal nodes

* Add index to network inputs, remove imports usage from flatten network

* Replace NodeOutput with NodeInput::Node

* Fully remove imports field, remove unnecessary identity nodes, move Output node to encapsulating network

* Replace previous_outputs with root_node, fix adding artboard/layer to empty network

* Import/Export UI nodes

* Display input/output types dynamically from compiled network

* Add LayerNodeIdentifer::ROOT_PARENT

* Prevent .to_node() on ROOT_PARENT

* Separate NodeGraphMessage and GraphOperationMessage

* General bug fixes with nested networks

* Change layer color, various bug fixes and improvements

* Fix disconnect and set node input for proto nodes and UI export node

* Dashed line to export for previewed node

* Fix deleting proto nodes and nodes that feed into export

* Allow modifications to nodes outside of nested network

* Get network from Node Id parameter

* Change root_node to previous_root_node

* Get TaggedValue from proto node implementation type when disconnecting

* Improve preview functionality and state

* Artboard position and delete children fix

* Name inputs/outputs based on DocumentNodeDefinition or type, fix new artboard/layer insertion

* replace "Link" with "Wire", adjust previewing

* Various bug fixes and improvements

* Modify Sample and Poisson-Disk points, fix incorrect input index and deleting currently viewed node

* Open demo artwork

* Fix opening already upgraded documents and refactor FrontendGraphDataType usages

* Fix deleting within network and other bugs

* Get default node input from compiled network when copying, fix previews, tests, demo artwork

* Code cleanup

* Hide EditorApi and add a comment describing unresolved Import node input types

* Code review

* Replace placeholder ROOT_PARENT NodeId with std::u64::MAX

* Breadcrumb padding

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
adamgerhant
2024-06-02 01:01:56 -07:00
committed by GitHub
parent e4d3faa52a
commit 6d74abb4de
77 changed files with 3924 additions and 2327 deletions

View File

@@ -37,9 +37,7 @@ fn main() {
fn add_network() -> NodeNetwork {
NodeNetwork {
imports: vec![],
exports: vec![NodeOutput::new(NodeId(0), 0)],
previous_outputs: None,
exports: vec![NodeInput::node(NodeId(0), 0)],
nodes: [DocumentNode {
name: "Blend Image".into(),
inputs: vec![NodeInput::Inline(InlineRust::new(
@@ -67,5 +65,6 @@ fn add_network() -> NodeNetwork {
.enumerate()
.map(|(id, node)| (NodeId(id as u64), node))
.collect(),
..Default::default()
}
}

View File

@@ -3,3 +3,7 @@ use crate::raster::Color;
// RENDERING
pub const LAYER_OUTLINE_STROKE_COLOR: Color = Color::BLACK;
pub const LAYER_OUTLINE_STROKE_WEIGHT: f64 = 1.;
// Fonts
pub const DEFAULT_FONT_FAMILY: &str = "Cabin";
pub const DEFAULT_FONT_STYLE: &str = "Normal (400)";

View File

@@ -134,16 +134,16 @@ impl ArtboardGroup {
}
}
pub struct ConstructLayerNode<GraphicElement, Stack> {
graphic_element: GraphicElement,
pub struct ConstructLayerNode<Stack, GraphicElement> {
stack: Stack,
graphic_element: GraphicElement,
}
#[node_fn(ConstructLayerNode)]
async fn construct_layer<Data: Into<GraphicElement>, Fut1: Future<Output = Data>, Fut2: Future<Output = GraphicGroup>>(
async fn construct_layer<Data: Into<GraphicElement>, Fut1: Future<Output = GraphicGroup>, Fut2: Future<Output = Data>>(
footprint: crate::transform::Footprint,
graphic_element: impl Node<crate::transform::Footprint, Output = Fut1>,
mut stack: impl Node<crate::transform::Footprint, Output = Fut2>,
mut stack: impl Node<crate::transform::Footprint, Output = Fut1>,
graphic_element: impl Node<crate::transform::Footprint, Output = Fut2>,
) -> GraphicGroup {
let graphic_element = self.graphic_element.eval(footprint).await;
let mut stack = self.stack.eval(footprint).await;
@@ -192,16 +192,16 @@ async fn construct_artboard<Fut: Future<Output = GraphicGroup>>(
clip,
}
}
pub struct AddArtboardNode<Artboard, ArtboardGroup> {
artboard: Artboard,
pub struct AddArtboardNode<ArtboardGroup, Artboard> {
artboards: ArtboardGroup,
artboard: Artboard,
}
#[node_fn(AddArtboardNode)]
async fn add_artboard<Data: Into<Artboard>, Fut1: Future<Output = Data>, Fut2: Future<Output = ArtboardGroup>>(
async fn add_artboard<Data: Into<Artboard>, Fut1: Future<Output = ArtboardGroup>, Fut2: Future<Output = Data>>(
footprint: Footprint,
artboard: impl Node<Footprint, Output = Fut1>,
mut artboards: impl Node<Footprint, Output = Fut2>,
artboards: impl Node<Footprint, Output = Fut1>,
artboard: impl Node<Footprint, Output = Fut2>,
) -> ArtboardGroup {
let artboard = self.artboard.eval(footprint).await;
let mut artboards = self.artboards.eval(footprint).await;

View File

@@ -177,7 +177,7 @@ impl<T> LetNode<T> {
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct EndLetNode<Input, Parameter> {
input: Input,
paramenter: PhantomData<Parameter>,
parameter: PhantomData<Parameter>,
}
impl<'i, T: 'i, Parameter: 'i + From<T>, Input> Node<'i, T> for EndLetNode<Input, Parameter>
where
@@ -192,7 +192,7 @@ where
impl<Input, Parameter> EndLetNode<Input, Parameter> {
pub const fn new(input: Input) -> EndLetNode<Input, Parameter> {
EndLetNode { input, paramenter: PhantomData }
EndLetNode { input, parameter: PhantomData }
}
}

View File

@@ -429,17 +429,17 @@ mod test {
pub fn map_result() {
let value: ClonedNode<Result<&u32, ()>> = ClonedNode(Ok(&4u32));
assert_eq!(value.eval(()), Ok(&4u32));
//let type_erased_clone = clone as &dyn for<'a> Node<'a, &'a u32, Output = u32>;
// let type_erased_clone = clone as &dyn for<'a> Node<'a, &'a u32, Output = u32>;
let map_result = MapResultNode::new(ValueNode::new(FnNode::new(|x: &u32| *x)));
//et type_erased = &map_result as &dyn for<'a> Node<'a, Result<&'a u32, ()>, Output = Result<u32, ()>>;
// let type_erased = &map_result as &dyn for<'a> Node<'a, Result<&'a u32, ()>, Output = Result<u32, ()>>;
assert_eq!(map_result.eval(Ok(&4u32)), Ok(4u32));
let fst = value.then(map_result);
//let type_erased = &fst as &dyn for<'a> Node<'a, (), Output = Result<u32, ()>>;
// let type_erased = &fst as &dyn for<'a> Node<'a, (), Output = Result<u32, ()>>;
assert_eq!(fst.eval(()), Ok(4u32));
}
#[test]
pub fn flat_map_result() {
let fst = ValueNode(Ok(&4u32)).then(CloneNode::new()); //.then(FlatMapResultNode::new(FnNode::new(|x| Ok(x))));
let fst = ValueNode(Ok(&4u32)).then(CloneNode::new());
let fn_node: FnNode<_, &u32, Result<&u32, _>> = FnNode::new(|_| Err(8u32));
assert_eq!(fn_node.eval(&4u32), Err(8u32));
let flat_map = FlatMapResultNode::new(ValueNode::new(fn_node));

View File

@@ -186,7 +186,7 @@ mod test {
let quantized = quantize_color(color, [quant; 4]);
assert_eq!(quantized.0, 0x7f7f7f7f);
let _dequantized = dequantize_color(quantized, [quant; 4]);
//assert_eq!(color, dequantized);
// assert_eq!(color, dequantized);
}
#[test]

View File

@@ -767,7 +767,7 @@ impl Color {
/// ```
/// use graphene_core::raster::color::Color;
/// let color = Color::from_rgbaf32(0.114, 0.103, 0.98, 0.97).unwrap();
/// //TODO: Add test
/// // TODO: Add test
/// ```
#[inline(always)]
pub fn to_rgba8_srgb(&self) -> [u8; 4] {

View File

@@ -118,7 +118,7 @@ impl PartialEq for TypeDescriptor {
(Some(id), Some(other_id)) => id == other_id,
_ => {
// TODO: Add a flag to disable this warning
//warn!("TypeDescriptor::eq: comparing types without ids based on name");
// warn!("TypeDescriptor::eq: comparing types without ids based on name");
self.name == other.name
}
}
@@ -214,6 +214,15 @@ impl Type {
Self::Future(_) => None,
}
}
pub fn nested_type(self) -> Type {
match self {
Self::Generic(_) => self,
Self::Concrete(_) => self,
Self::Fn(_, output) => output.nested_type(),
Self::Future(_) => self,
}
}
}
fn format_type(ty: &str) -> String {

View File

@@ -141,7 +141,7 @@ pub fn serialize_gpu(networks: &[ProtoNetwork], io: &ShaderIO) -> anyhow::Result
let mut output_nodes = Vec::new();
for network in networks {
dbg!(&network);
//assert_eq!(network.inputs.len(), io.inputs.iter().filter(|x| !x.is_output()).count());
// assert_eq!(network.inputs.len(), io.inputs.iter().filter(|x| !x.is_output()).count());
#[derive(serde::Serialize, Debug)]
struct Node {
id: String,
@@ -215,10 +215,10 @@ pub fn compile(dir: &Path) -> Result<spirv_builder::CompileResult, spirv_builder
.preserve_bindings(true)
.release(true)
.spirv_metadata(SpirvMetadata::Full)
//.scalar_block_layout(true)
// .scalar_block_layout(true)
.relax_logical_pointer(true)
//.capability(spirv_builder::Capability::Float64)
//.capability(spirv_builder::Capability::VariablePointersStorageBuffer)
// .capability(spirv_builder::Capability::Float64)
// .capability(spirv_builder::Capability::VariablePointersStorageBuffer)
.extra_arg("no-early-report-zombies")
.extra_arg("no-infer-storage-classes")
.extra_arg("spirt-passes=qptr")

View File

@@ -4,39 +4,41 @@
#[cfg(target_arch = "spirv")]
extern crate spirv_std;
//#[cfg(target_arch = "spirv")]
//pub mod gpu {
//use super::*;
use spirv_std::spirv;
use spirv_std::glam;
use spirv_std::glam::{UVec3, Vec2, Mat2, BVec2};
// #[cfg(target_arch = "spirv")]
// pub mod gpu {
// use super::*;
#[allow(unused)]
#[spirv(compute(threads({{compute_threads}})))]
pub fn eval (
#[spirv(global_invocation_id)] _global_index: UVec3,
{% for input in inputs %}
{{input}},
{% endfor %}
) {
use graphene_core::{Node, NodeMut};
use graphene_core::raster::adjustments::{BlendMode, BlendNode};
use graphene_core::Color;
use spirv_std::spirv;
use spirv_std::glam;
use spirv_std::glam::{UVec3, Vec2, Mat2, BVec2};
{% for input in input_nodes %}
let _i{{input.index}} = graphene_core::value::CopiedNode::new(*i{{input.index}});
let _{{input.id}} = {{input.fqn}}::new({% for arg in input.args %}{{arg}}, {% endfor %});
let {{input.id}} = graphene_core::structural::ComposeNode::new(_i{{input.index}}, _{{input.id}});
{% endfor %}
#[allow(unused)]
#[spirv(compute(threads({{compute_threads}})))]
pub fn eval (
#[spirv(global_invocation_id)] _global_index: UVec3,
{% for input in inputs %}
{{input}},
{% endfor %}
) {
use graphene_core::{Node, NodeMut};
use graphene_core::raster::adjustments::{BlendMode, BlendNode};
use graphene_core::Color;
{% for node in nodes %}
let mut {{node.id}} = {{node.fqn}}::new({% for arg in node.args %}{{arg}}, {% endfor %});
{% endfor %}
{% for input in input_nodes %}
let _i{{input.index}} = graphene_core::value::CopiedNode::new(*i{{input.index}});
let _{{input.id}} = {{input.fqn}}::new({% for arg in input.args %}{{arg}}, {% endfor %});
let {{input.id}} = graphene_core::structural::ComposeNode::new(_i{{input.index}}, _{{input.id}});
{% endfor %}
{% for output in output_nodes %}
let v = {{output}}.eval(());
o{{loop.index0}}[(_global_index.y * i0 + _global_index.x) as usize] = v;
{% endfor %}
// TODO: Write output to buffer
}
//}
{% for node in nodes %}
let mut {{node.id}} = {{node.fqn}}::new({% for arg in node.args %}{{arg}}, {% endfor %});
{% endfor %}
{% for output in output_nodes %}
let v = {{output}}.eval(());
o{{loop.index0}}[(_global_index.y * i0 + _global_index.x) as usize] = v;
{% endfor %}
// TODO: Write output to buffer
}
// }

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@ use graphene_core::{Color, Node, Type};
use dyn_any::DynAny;
pub use dyn_any::StaticType;
pub use glam::{DAffine2, DVec2, UVec2};
pub use glam::{DAffine2, DVec2, IVec2, UVec2};
use std::hash::Hash;
pub use std::sync::Arc;
@@ -25,6 +25,7 @@ pub enum TaggedValue {
F64(f64),
Bool(bool),
UVec2(UVec2),
IVec2(IVec2),
DVec2(DVec2),
OptionalDVec2(Option<DVec2>),
DAffine2(DAffine2),
@@ -69,10 +70,9 @@ pub enum TaggedValue {
Segments(Vec<graphene_core::raster::ImageFrame<Color>>),
DocumentNode(DocumentNode),
GraphicGroup(graphene_core::GraphicGroup),
Artboard(graphene_core::Artboard),
GraphicElement(graphene_core::GraphicElement),
ArtboardGroup(graphene_core::ArtboardGroup),
Curve(graphene_core::raster::curve::Curve),
IVec2(glam::IVec2),
SurfaceFrame(graphene_core::SurfaceFrame),
Footprint(graphene_core::transform::Footprint),
RenderOutput(RenderOutput),
@@ -93,6 +93,7 @@ impl Hash for TaggedValue {
Self::F64(x) => x.to_bits().hash(state),
Self::Bool(x) => x.hash(state),
Self::UVec2(x) => x.to_array().iter().for_each(|x| x.hash(state)),
Self::IVec2(x) => x.hash(state),
Self::DVec2(x) => x.to_array().iter().for_each(|x| x.to_bits().hash(state)),
Self::OptionalDVec2(None) => 0.hash(state),
Self::OptionalDVec2(Some(x)) => {
@@ -150,10 +151,9 @@ impl Hash for TaggedValue {
}
Self::DocumentNode(x) => x.hash(state),
Self::GraphicGroup(x) => x.hash(state),
Self::Artboard(x) => x.hash(state),
Self::GraphicElement(x) => x.hash(state),
Self::ArtboardGroup(x) => x.hash(state),
Self::Curve(x) => x.hash(state),
Self::IVec2(x) => x.hash(state),
Self::SurfaceFrame(x) => x.hash(state),
Self::Footprint(x) => x.hash(state),
Self::RenderOutput(x) => x.hash(state),
@@ -175,6 +175,7 @@ impl<'a> TaggedValue {
TaggedValue::F64(x) => Box::new(x),
TaggedValue::Bool(x) => Box::new(x),
TaggedValue::UVec2(x) => Box::new(x),
TaggedValue::IVec2(x) => Box::new(x),
TaggedValue::DVec2(x) => Box::new(x),
TaggedValue::OptionalDVec2(x) => Box::new(x),
TaggedValue::DAffine2(x) => Box::new(x),
@@ -218,10 +219,9 @@ impl<'a> TaggedValue {
TaggedValue::Segments(x) => Box::new(x),
TaggedValue::DocumentNode(x) => Box::new(x),
TaggedValue::GraphicGroup(x) => Box::new(x),
TaggedValue::Artboard(x) => Box::new(x),
TaggedValue::GraphicElement(x) => Box::new(x),
TaggedValue::ArtboardGroup(x) => Box::new(x),
TaggedValue::Curve(x) => Box::new(x),
TaggedValue::IVec2(x) => Box::new(x),
TaggedValue::SurfaceFrame(x) => Box::new(x),
TaggedValue::Footprint(x) => Box::new(x),
TaggedValue::RenderOutput(x) => Box::new(x),
@@ -254,6 +254,7 @@ impl<'a> TaggedValue {
TaggedValue::F64(_) => concrete!(f64),
TaggedValue::Bool(_) => concrete!(bool),
TaggedValue::UVec2(_) => concrete!(UVec2),
TaggedValue::IVec2(_) => concrete!(IVec2),
TaggedValue::DVec2(_) => concrete!(DVec2),
TaggedValue::OptionalDVec2(_) => concrete!(Option<DVec2>),
TaggedValue::Image(_) => concrete!(graphene_core::raster::Image<Color>),
@@ -297,10 +298,9 @@ impl<'a> TaggedValue {
TaggedValue::Segments(_) => concrete!(graphene_core::raster::IndexNode<Vec<graphene_core::raster::ImageFrame<Color>>>),
TaggedValue::DocumentNode(_) => concrete!(crate::document::DocumentNode),
TaggedValue::GraphicGroup(_) => concrete!(graphene_core::GraphicGroup),
TaggedValue::Artboard(_) => concrete!(graphene_core::Artboard),
TaggedValue::GraphicElement(_) => concrete!(graphene_core::GraphicElement),
TaggedValue::ArtboardGroup(_) => concrete!(graphene_core::ArtboardGroup),
TaggedValue::Curve(_) => concrete!(graphene_core::raster::curve::Curve),
TaggedValue::IVec2(_) => concrete!(glam::IVec2),
TaggedValue::SurfaceFrame(_) => concrete!(graphene_core::SurfaceFrame),
TaggedValue::Footprint(_) => concrete!(graphene_core::transform::Footprint),
TaggedValue::RenderOutput(_) => concrete!(RenderOutput),
@@ -322,6 +322,7 @@ impl<'a> TaggedValue {
x if x == TypeId::of::<f64>() => Ok(TaggedValue::F64(*downcast(input).unwrap())),
x if x == TypeId::of::<bool>() => Ok(TaggedValue::Bool(*downcast(input).unwrap())),
x if x == TypeId::of::<UVec2>() => Ok(TaggedValue::UVec2(*downcast(input).unwrap())),
x if x == TypeId::of::<IVec2>() => Ok(TaggedValue::IVec2(*downcast(input).unwrap())),
x if x == TypeId::of::<DVec2>() => Ok(TaggedValue::DVec2(*downcast(input).unwrap())),
x if x == TypeId::of::<Option<DVec2>>() => Ok(TaggedValue::OptionalDVec2(*downcast(input).unwrap())),
x if x == TypeId::of::<graphene_core::raster::Image<Color>>() => Ok(TaggedValue::Image(*downcast(input).unwrap())),
@@ -364,8 +365,8 @@ impl<'a> TaggedValue {
x if x == TypeId::of::<graphene_core::raster::IndexNode<Vec<graphene_core::raster::ImageFrame<Color>>>>() => Ok(TaggedValue::Segments(*downcast(input).unwrap())),
x if x == TypeId::of::<crate::document::DocumentNode>() => Ok(TaggedValue::DocumentNode(*downcast(input).unwrap())),
x if x == TypeId::of::<graphene_core::GraphicGroup>() => Ok(TaggedValue::GraphicGroup(*downcast(input).unwrap())),
x if x == TypeId::of::<graphene_core::Artboard>() => Ok(TaggedValue::Artboard(*downcast(input).unwrap())),
x if x == TypeId::of::<glam::IVec2>() => Ok(TaggedValue::IVec2(*downcast(input).unwrap())),
x if x == TypeId::of::<graphene_core::GraphicElement>() => Ok(TaggedValue::GraphicElement(*downcast(input).unwrap())),
x if x == TypeId::of::<graphene_core::ArtboardGroup>() => Ok(TaggedValue::ArtboardGroup(*downcast(input).unwrap())),
x if x == TypeId::of::<graphene_core::SurfaceFrame>() => Ok(TaggedValue::SurfaceFrame(*downcast(input).unwrap())),
x if x == TypeId::of::<RenderOutput>() => Ok(TaggedValue::RenderOutput(*downcast(input).unwrap())),
x if x == TypeId::of::<graphene_core::WasmSurfaceHandleFrame>() => {
@@ -379,6 +380,93 @@ impl<'a> TaggedValue {
_ => Err(format!("Cannot convert {:?} to TaggedValue", DynAny::type_name(input.as_ref()))),
}
}
pub fn from_type(input: &Type) -> Self {
match input {
Type::Generic(_) => {
log::warn!("Generic type should be resolved");
TaggedValue::None
}
Type::Concrete(concrete_type) => {
let Some(internal_id) = concrete_type.id else {
return TaggedValue::None;
};
use std::any::TypeId;
// TODO: Add default implementations for types such as TaggedValue::Subpaths, and use the defaults here and in document_node_types
// Tries using the default for the tagged value type. If it not implemented, then uses the default used in document_node_types. If it is not used there, then TaggedValue::None is returned.
match internal_id {
x if x == TypeId::of::<()>() => TaggedValue::None,
x if x == TypeId::of::<String>() => TaggedValue::String(Default::default()),
x if x == TypeId::of::<u32>() => TaggedValue::U32(Default::default()),
x if x == TypeId::of::<u64>() => TaggedValue::U64(Default::default()),
x if x == TypeId::of::<f64>() => TaggedValue::F64(Default::default()),
x if x == TypeId::of::<bool>() => TaggedValue::Bool(Default::default()),
x if x == TypeId::of::<UVec2>() => TaggedValue::UVec2(Default::default()),
x if x == TypeId::of::<IVec2>() => TaggedValue::IVec2(Default::default()),
x if x == TypeId::of::<DVec2>() => TaggedValue::DVec2(Default::default()),
x if x == TypeId::of::<Option<DVec2>>() => TaggedValue::OptionalDVec2(Default::default()),
x if x == TypeId::of::<graphene_core::raster::Image<Color>>() => TaggedValue::Image(Default::default()),
x if x == TypeId::of::<ImaginateCache>() => TaggedValue::ImaginateCache(Default::default()),
x if x == TypeId::of::<graphene_core::raster::ImageFrame<Color>>() => TaggedValue::ImageFrame(Default::default()),
x if x == TypeId::of::<graphene_core::raster::Color>() => TaggedValue::Color(Default::default()),
x if x == TypeId::of::<Vec<bezier_rs::Subpath<graphene_core::uuid::ManipulatorGroupId>>>() => TaggedValue::Subpaths(vec![]),
x if x == TypeId::of::<Arc<bezier_rs::Subpath<graphene_core::uuid::ManipulatorGroupId>>>() => TaggedValue::None,
x if x == TypeId::of::<BlendMode>() => TaggedValue::BlendMode(Default::default()),
x if x == TypeId::of::<ImaginateSamplingMethod>() => TaggedValue::ImaginateSamplingMethod(Default::default()),
x if x == TypeId::of::<ImaginateMaskStartingFill>() => TaggedValue::ImaginateMaskStartingFill(Default::default()),
x if x == TypeId::of::<ImaginateController>() => TaggedValue::ImaginateController(Default::default()),
x if x == TypeId::of::<DAffine2>() => TaggedValue::DAffine2(Default::default()),
x if x == TypeId::of::<LuminanceCalculation>() => TaggedValue::LuminanceCalculation(Default::default()),
x if x == TypeId::of::<graphene_core::vector::VectorData>() => TaggedValue::VectorData(Default::default()),
x if x == TypeId::of::<graphene_core::vector::style::Fill>() => TaggedValue::Fill(Default::default()),
x if x == TypeId::of::<graphene_core::vector::style::Stroke>() => TaggedValue::Stroke(Default::default()),
x if x == TypeId::of::<Vec<f64>>() => TaggedValue::VecF64(Default::default()),
x if x == TypeId::of::<Vec<DVec2>>() => TaggedValue::VecDVec2(Default::default()),
x if x == TypeId::of::<graphene_core::raster::RedGreenBlue>() => TaggedValue::RedGreenBlue(graphene_core::raster::RedGreenBlue::Red),
x if x == TypeId::of::<graphene_core::raster::RedGreenBlueAlpha>() => TaggedValue::RedGreenBlueAlpha(graphene_core::raster::RedGreenBlueAlpha::Red),
x if x == TypeId::of::<graphene_core::raster::NoiseType>() => TaggedValue::NoiseType(graphene_core::raster::NoiseType::Perlin),
x if x == TypeId::of::<graphene_core::raster::FractalType>() => TaggedValue::FractalType(graphene_core::raster::FractalType::None),
x if x == TypeId::of::<graphene_core::raster::CellularDistanceFunction>() => TaggedValue::CellularDistanceFunction(graphene_core::raster::CellularDistanceFunction::Euclidean),
x if x == TypeId::of::<graphene_core::raster::CellularReturnType>() => TaggedValue::CellularReturnType(graphene_core::raster::CellularReturnType::Nearest),
x if x == TypeId::of::<graphene_core::raster::DomainWarpType>() => TaggedValue::DomainWarpType(graphene_core::raster::DomainWarpType::None),
x if x == TypeId::of::<graphene_core::raster::RelativeAbsolute>() => TaggedValue::RelativeAbsolute(graphene_core::raster::RelativeAbsolute::Relative),
x if x == TypeId::of::<graphene_core::raster::SelectiveColorChoice>() => TaggedValue::SelectiveColorChoice(graphene_core::raster::SelectiveColorChoice::Reds),
x if x == TypeId::of::<graphene_core::vector::style::LineCap>() => TaggedValue::LineCap(graphene_core::vector::style::LineCap::Butt),
x if x == TypeId::of::<graphene_core::vector::style::LineJoin>() => TaggedValue::LineJoin(graphene_core::vector::style::LineJoin::Miter),
x if x == TypeId::of::<graphene_core::vector::style::FillType>() => TaggedValue::FillType(graphene_core::vector::style::FillType::Solid),
x if x == TypeId::of::<graphene_core::vector::style::GradientType>() => TaggedValue::GradientType(Default::default()),
x if x == TypeId::of::<Vec<(f64, graphene_core::Color)>>() => TaggedValue::GradientPositions(Default::default()),
x if x == TypeId::of::<graphene_core::quantization::QuantizationChannels>() => TaggedValue::Quantization(Default::default()),
x if x == TypeId::of::<Option<graphene_core::Color>>() => TaggedValue::OptionalColor(Default::default()),
x if x == TypeId::of::<Vec<graphene_core::uuid::ManipulatorGroupId>>() => TaggedValue::ManipulatorGroupIds(Default::default()),
x if x == TypeId::of::<graphene_core::text::Font>() => TaggedValue::Font(graphene_core::text::Font::new(
graphene_core::consts::DEFAULT_FONT_FAMILY.into(),
graphene_core::consts::DEFAULT_FONT_STYLE.into(),
)),
x if x == TypeId::of::<Vec<graphene_core::vector::brush_stroke::BrushStroke>>() => TaggedValue::BrushStrokes(Default::default()),
x if x == TypeId::of::<BrushCache>() => TaggedValue::BrushCache(Default::default()),
x if x == TypeId::of::<graphene_core::raster::IndexNode<Vec<graphene_core::raster::ImageFrame<Color>>>>() => TaggedValue::Segments(Default::default()),
x if x == TypeId::of::<crate::document::DocumentNode>() => TaggedValue::DocumentNode(Default::default()),
x if x == TypeId::of::<graphene_core::GraphicGroup>() => TaggedValue::GraphicGroup(Default::default()),
x if x == TypeId::of::<graphene_core::GraphicElement>() => TaggedValue::GraphicElement(Default::default()),
x if x == TypeId::of::<graphene_core::Artboard>() => TaggedValue::ArtboardGroup(graphene_core::ArtboardGroup::EMPTY),
x if x == TypeId::of::<graphene_core::ArtboardGroup>() => TaggedValue::ArtboardGroup(graphene_core::ArtboardGroup::EMPTY),
x if x == TypeId::of::<graphene_core::SurfaceFrame>() => TaggedValue::None,
x if x == TypeId::of::<RenderOutput>() => TaggedValue::None,
x if x == TypeId::of::<graphene_core::WasmSurfaceHandleFrame>() => TaggedValue::None,
x if x == TypeId::of::<graphene_core::transform::Footprint>() => TaggedValue::Footprint(Default::default()),
x if x == TypeId::of::<Vec<Color>>() => TaggedValue::Palette(Default::default()),
x if x == TypeId::of::<graphene_core::vector::misc::CentroidType>() => TaggedValue::CentroidType(Default::default()),
x if x == TypeId::of::<graphene_core::vector::misc::BooleanOperation>() => TaggedValue::BooleanOperation(Default::default()),
_ => TaggedValue::None,
}
}
Type::Fn(_, output) => TaggedValue::from_type(output),
Type::Future(_) => {
log::warn!("Future type not used");
TaggedValue::None
}
}
}
}
pub struct UpcastNode {

View File

@@ -15,7 +15,7 @@ impl Compiler {
network.flatten(id);
}
network.remove_redundant_id_nodes();
network.remove_dead_nodes();
network.remove_dead_nodes(0);
let proto_networks = network.into_proto_networks();
let proto_networks_result: Vec<ProtoNetwork> = proto_networks

View File

@@ -536,7 +536,6 @@ impl ProtoNetwork {
}
}
}
debug!("Sorted order {sorted:?}");
sorted
}*/

View File

@@ -52,9 +52,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
};
loop {
//println!("executing");
let _result = (&executor).execute(editor_api.clone()).await?;
//println!("result: {result:?}");
std::thread::sleep(std::time::Duration::from_millis(16));
}
}
@@ -92,67 +90,11 @@ fn create_executor(_document_string: String) -> Result<DynamicExecutor, Box<dyn
// Ok(executor)
}
pub fn wrap_network_in_scope(mut network: NodeNetwork) -> NodeNetwork {
let node_ids = network.nodes.keys().copied().collect::<Vec<_>>();
network.generate_node_paths(&[]);
for id in node_ids {
network.flatten(id);
}
let mut network_inputs = Vec::new();
let mut input_type = None;
for (id, node) in network.nodes.iter() {
for input in node.inputs.iter() {
if let NodeInput::Network(_) = input {
if input_type.is_none() {
input_type = Some(input.clone());
}
assert_eq!(input, input_type.as_ref().unwrap(), "Networks wrapped in scope must have the same input type");
network_inputs.push(*id);
}
}
}
let len = network_inputs.len();
network.imports = network_inputs;
// if the network has no inputs, it doesn't need to be wrapped in a scope
if len == 0 {
return network;
}
let inner_network = DocumentNode {
name: "Scope".to_string(),
implementation: DocumentNodeImplementation::Network(network),
inputs: core::iter::repeat(NodeInput::node(NodeId(0), 1)).take(len).collect(),
..Default::default()
};
// wrap the inner network in a scope
let nodes = vec![
begin_scope(),
inner_network,
DocumentNode {
name: "End Scope".to_string(),
implementation: DocumentNodeImplementation::proto("graphene_core::memo::EndLetNode<_, _>"),
inputs: vec![NodeInput::node(NodeId(0), 0), NodeInput::node(NodeId(1), 0)],
..Default::default()
},
];
NodeNetwork {
imports: vec![NodeId(0)],
exports: vec![NodeOutput::new(NodeId(2), 0)],
nodes: nodes.into_iter().enumerate().map(|(id, node)| (NodeId(id as u64), node)).collect(),
..Default::default()
}
}
fn begin_scope() -> DocumentNode {
DocumentNode {
name: "Begin Scope".to_string(),
implementation: DocumentNodeImplementation::Network(NodeNetwork {
imports: vec![NodeId(0)],
exports: vec![NodeOutput::new(NodeId(1), 0), NodeOutput::new(NodeId(2), 0)],
exports: vec![NodeInput::node(NodeId(1), 0), NodeInput::node(NodeId(2), 0)],
nodes: [
DocumentNode {
name: "SetNode".to_string(),
@@ -181,7 +123,7 @@ fn begin_scope() -> DocumentNode {
..Default::default()
}),
inputs: vec![NodeInput::Network(concrete!(WasmEditorApi))],
inputs: vec![NodeInput::network(concrete!(WasmEditorApi), 0)],
..Default::default()
}
}

View File

@@ -285,19 +285,19 @@ mod test {
#[test]
#[should_panic]
pub fn dyn_input_invalid_eval_panic() {
//let add = DynAnyNode::new(AddPairNode::new()).into_type_erased();
//add.eval(Box::new(&("32", 32u32)));
// let add = DynAnyNode::new(AddPairNode::new()).into_type_erased();
// add.eval(Box::new(&("32", 32u32)));
let dyn_any = DynAnyNode::<(u32, u32), u32, _>::new(FutureWrapperNode { node: AddPairNode::new() });
let type_erased = Box::new(dyn_any) as TypeErasedBox;
let _ref_type_erased = type_erased.as_ref();
//let type_erased = Box::pin(dyn_any) as TypeErasedBox<'_>;
// let type_erased = Box::pin(dyn_any) as TypeErasedBox<'_>;
type_erased.eval(Box::new(&("32", 32u32)));
}
#[test]
pub fn dyn_input_compose() {
//let add = DynAnyNode::new(AddPairNode::new()).into_type_erased();
//add.eval(Box::new(&("32", 32u32)));
// let add = DynAnyNode::new(AddPairNode::new()).into_type_erased();
// add.eval(Box::new(&("32", 32u32)));
let dyn_any = DynAnyNode::<(u32, u32), u32, _>::new(FutureWrapperNode { node: AddPairNode::new() });
let type_erased = Box::new(dyn_any) as TypeErasedBox<'_>;
type_erased.eval(Box::new((4u32, 2u32)));
@@ -306,8 +306,8 @@ mod test {
let type_erased_id = Box::new(any_id) as TypeErasedBox;
let type_erased = ComposeTypeErased::new(NodeContainer::new(type_erased), NodeContainer::new(type_erased_id));
type_erased.eval(Box::new((4u32, 2u32)));
//let downcast: DowncastBothNode<(u32, u32), u32> = DowncastBothNode::new(type_erased.as_ref());
//downcast.eval((4u32, 2u32));
// let downcast: DowncastBothNode<(u32, u32), u32> = DowncastBothNode::new(type_erased.as_ref());
// downcast.eval((4u32, 2u32));
}
// TODO: Fix this test

View File

@@ -169,11 +169,10 @@ async fn create_compute_pass_descriptor<T: Clone + Pixel + StaticTypeSized>(
log::debug!("inner_network: {inner_network:?}");
let network = NodeNetwork {
imports: vec![NodeId(2), NodeId(1)], //vec![0, 1],
#[cfg(feature = "quantization")]
exports: vec![NodeOutput::new(NodeId(5), 0)],
exports: vec![NodeInput::node(NodeId(5), 0)],
#[cfg(not(feature = "quantization"))]
exports: vec![NodeOutput::new(NodeId(3), 0)],
exports: vec![NodeInput::node(NodeId(3), 0)],
nodes: [
DocumentNode {
name: "Slice".into(),
@@ -183,19 +182,19 @@ async fn create_compute_pass_descriptor<T: Clone + Pixel + StaticTypeSized>(
},
DocumentNode {
name: "Quantization".into(),
inputs: vec![NodeInput::Network(concrete!(quantization::Quantization))],
inputs: vec![NodeInput::network(concrete!(quantization::Quantization), 1)],
implementation: DocumentNodeImplementation::ProtoNode("graphene_core::ops::IdentityNode".into()),
..Default::default()
},
DocumentNode {
name: "Width".into(),
inputs: vec![NodeInput::Network(concrete!(u32))],
inputs: vec![NodeInput::network(concrete!(u32), 0)],
implementation: DocumentNodeImplementation::ProtoNode("graphene_core::ops::IdentityNode".into()),
..Default::default()
},
/*DocumentNode {
name: "Index".into(),
//inputs: vec![NodeInput::Network(concrete!(UVec3))],
// inputs: vec![NodeInput::Network(concrete!(UVec3))],
inputs: vec![NodeInput::Inline(InlineRust::new("i1.x as usize".into(), concrete![u32]))],
implementation: DocumentNodeImplementation::ProtoNode("graphene_core::value::CopiedNode".into()),
..Default::default()
@@ -237,7 +236,7 @@ async fn create_compute_pass_descriptor<T: Clone + Pixel + StaticTypeSized>(
NodeInput::node(NodeId(5), 0),
NodeInput::Inline(InlineRust::new(
"|x| o0[(_global_index.y * i1 + _global_index.x) as usize] = x".into(),
//"|x|()".into(),
// "|x|()".into(),
Type::Fn(Box::new(concrete!(PackedPixel)), Box::new(concrete!(()))),
)),
],
@@ -257,7 +256,7 @@ async fn create_compute_pass_descriptor<T: Clone + Pixel + StaticTypeSized>(
log::debug!("compiling shader");
let shader = compilation_client::compile(
proto_networks,
vec![concrete!(u32), concrete!(Color)], //, concrete!(u32)],
vec![concrete!(u32), concrete!(Color)],
vec![concrete!(Color)],
ShaderIO {
#[cfg(feature = "quantization")]
@@ -265,7 +264,7 @@ async fn create_compute_pass_descriptor<T: Clone + Pixel + StaticTypeSized>(
ShaderInput::UniformBuffer((), concrete!(u32)),
ShaderInput::StorageBuffer((), concrete!(PackedPixel)),
ShaderInput::UniformBuffer((), concrete!(quantization::QuantizationChannels)),
//ShaderInput::Constant(gpu_executor::GPUConstant::GlobalInvocationId),
// ShaderInput::Constant(gpu_executor::GPUConstant::GlobalInvocationId),
ShaderInput::OutputBuffer((), concrete!(PackedPixel)),
],
#[cfg(not(feature = "quantization"))]
@@ -282,19 +281,19 @@ async fn create_compute_pass_descriptor<T: Clone + Pixel + StaticTypeSized>(
)
.await
.unwrap();
//return ImageFrame::empty();
// return ImageFrame::empty();
let len: usize = image.image.data.len();
/*
let canvas = editor_api.application_io.create_surface();
let surface = unsafe { executor.create_surface(canvas) }.unwrap();
//log::debug!("id: {surface:?}");
// log::debug!("id: {surface:?}");
let surface_id = surface.surface_id;
let texture = executor.create_texture_buffer(image.image.clone(), TextureBufferOptions::Texture).unwrap();
//executor.create_render_pass(texture, surface).unwrap();
// executor.create_render_pass(texture, surface).unwrap();
let frame = SurfaceFrame {
surface_id,
@@ -391,7 +390,7 @@ fn map_gpu_single_image(input: Image<Color>, node: String) -> Image<Color> {
inputs: vec![NodeId(0)],
disabled: vec![],
previous_outputs: None,
outputs: vec![NodeOutput::new(NodeId(0), 0)],
outputs: vec![NodeInput::node(NodeId(0), 0)],
nodes: [(
NodeId(0),
DocumentNode {
@@ -434,8 +433,7 @@ async fn blend_gpu_image(foreground: ImageFrame<Color>, background: ImageFrame<C
let compiler = graph_craft::graphene_compiler::Compiler {};
let network = NodeNetwork {
imports: vec![],
exports: vec![NodeOutput::new(NodeId(0), 0)],
exports: vec![NodeInput::node(NodeId(0), 0)],
nodes: [DocumentNode {
name: "BlendOp".into(),
inputs: vec![NodeInput::Inline(InlineRust::new(

View File

@@ -2,8 +2,8 @@
#[macro_use]
extern crate log;
//pub mod value;
//#![feature(const_type_name)]
// pub mod value;
// #![feature(const_type_name)]
pub mod raster;

View File

@@ -96,8 +96,8 @@ fn create_distribution(data: Vec<f64>, samples: usize, channel: usize) -> Vec<(f
let max = *data.iter().max_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal)).unwrap();
let data: Vec<f64> = data.iter().map(|x| x / max).collect();
dbg!(max);
//let data = autoquant::generate_normal_distribution(3.0, 1.1, 1000);
//data.iter_mut().for_each(|x| *x = x.abs());
// let data = autoquant::generate_normal_distribution(3.0, 1.1, 1000);
// data.iter_mut().for_each(|x| *x = x.abs());
let mut dist = autoquant::integrate_distribution(data);
autoquant::drop_duplicates(&mut dist);
let dist = autoquant::normalize_distribution(dist.as_slice());

View File

@@ -85,6 +85,8 @@ impl DynamicExecutor {
pub fn document_node_types(&self) -> ResolvedDocumentNodeTypes {
let mut resolved_document_node_types = ResolvedDocumentNodeTypes::default();
// TODO: https://github.com/GraphiteEditor/Graphite/issues/1767
// TODO: Non exposed inputs are not added to the inputs_source_map, so they are not included in the resolved_document_node_types. The type is still available in the typing_context. This only affects the UI-only "Import" node.
for (source, &(protonode_id, protonode_index)) in self.tree.inputs_source_map() {
let Some(node_io) = self.typing_context.type_of(protonode_id) else { continue };
let Some(ty) = [&node_io.input].into_iter().chain(&node_io.parameters).nth(protonode_index) else {
@@ -206,7 +208,7 @@ impl BorrowTree {
ConstructionArgs::Value(value) => {
let upcasted = UpcastNode::new(value.to_owned());
let node = Box::new(upcasted) as TypeErasedBox<'_>;
let node = NodeContainer::new(node);
let node: std::rc::Rc<NodeContainer> = NodeContainer::new(node);
self.store_node(node, id);
}
ConstructionArgs::Inline(_) => unimplemented!("Inline nodes are not supported yet"),
@@ -242,7 +244,7 @@ mod test {
let mut tree = BorrowTree::default();
let val_1_protonode = ProtoNode::value(ConstructionArgs::Value(TaggedValue::U32(2u32)), vec![]);
let context = TypingContext::default();
let future = tree.push_node(NodeId(0), val_1_protonode, &context); //.await.unwrap();
let future = tree.push_node(NodeId(0), val_1_protonode, &context);
futures::executor::block_on(future).unwrap();
let _node = tree.get(NodeId(0)).unwrap();
let result = futures::executor::block_on(tree.eval(NodeId(0), ()));

View File

@@ -15,14 +15,13 @@ mod tests {
fn add_network() -> NodeNetwork {
NodeNetwork {
imports: vec![NodeId(0), NodeId(0)],
exports: vec![NodeOutput::new(NodeId(1), 0)],
exports: vec![NodeInput::node(NodeId(1), 0)],
nodes: [
(
NodeId(0),
DocumentNode {
name: "Cons".into(),
inputs: vec![NodeInput::Network(concrete!(u32)), NodeInput::Network(concrete!(&u32))],
inputs: vec![NodeInput::network(concrete!(u32), 0), NodeInput::network(concrete!(&u32), 1)],
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::structural::ConsNode<_, _>")),
..Default::default()
},
@@ -44,14 +43,13 @@ mod tests {
}
let network = NodeNetwork {
imports: vec![NodeId(0)],
exports: vec![NodeOutput::new(NodeId(0), 0)],
exports: vec![NodeInput::node(NodeId(0), 0)],
nodes: [(
NodeId(0),
DocumentNode {
name: "Inc".into(),
inputs: vec![
NodeInput::Network(concrete!(u32)),
NodeInput::network(concrete!(u32), 0),
NodeInput::Value {
tagged_value: graph_craft::document::value::TaggedValue::U32(1u32),
exposed: false,
@@ -84,15 +82,14 @@ mod tests {
use graph_craft::*;
let network = NodeNetwork {
imports: vec![NodeId(0)],
exports: vec![NodeOutput::new(NodeId(1), 0)],
exports: vec![NodeInput::node(NodeId(1), 0)],
nodes: [
// Simple identity node taking a number as input from outside the graph
(
NodeId(0),
DocumentNode {
name: "id".into(),
inputs: vec![NodeInput::Network(concrete!(u32))],
inputs: vec![NodeInput::network(concrete!(u32), 0)],
implementation: DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier::new("graphene_core::ops::IdentityNode")),
..Default::default()
},

View File

@@ -100,7 +100,7 @@ macro_rules! async_node {
graphene_std::any::PanicNode::<$arg, core::pin::Pin<Box<dyn core::future::Future<Output = $type>>>>::new()
),*);
// TODO: Propagate the future type through the node graph
//let params = vec![$(Type::Fn(Box::new(concrete!(())), Box::new(Type::Future(Box::new(concrete!($type)))))),*];
// let params = vec![$(Type::Fn(Box::new(concrete!(())), Box::new(Type::Future(Box::new(concrete!($type)))))),*];
let params = vec![$(fn_type!($arg, $type)),*];
let mut node_io = NodeIO::<'_, $input>::to_node_io(&node, params);
node_io.input = concrete!(<$input as StaticType>::Static);
@@ -177,10 +177,10 @@ macro_rules! raster_node {
}};
}
//TODO: turn into hashmap
// TODO: turn into hashmap
fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeConstructor>> {
let node_types: Vec<Vec<(ProtoNodeIdentifier, NodeConstructor, NodeIOTypes)>> = vec![
//register_node!(graphene_core::ops::IdentityNode, input: Any<'_>, params: []),
// register_node!(graphene_core::ops::IdentityNode, input: Any<'_>, params: []),
vec![(
ProtoNodeIdentifier::new("graphene_core::ops::IdentityNode"),
|_| Box::pin(async move { FutureWrapperNode::new(IdentityNode::new()).into_type_erased() }),
@@ -400,7 +400,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
Box::pin(async move {
let document_node: DowncastBothNode<(), graph_craft::document::DocumentNode> = DowncastBothNode::new(args[0].clone());
let editor_api: DowncastBothNode<(), WasmEditorApi> = DowncastBothNode::new(args[1].clone());
//let document_node = ClonedNode::new(document_node.eval(()));
// let document_node = ClonedNode::new(document_node.eval(()));
let node = graphene_std::gpu_nodes::MapGpuNode::new(document_node, editor_api);
let any: DynAnyNode<ImageFrame<Color>, _, _> = graphene_std::any::DynAnyNode::new(node);
any.into_type_erased()
@@ -700,7 +700,6 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
async_node!(graphene_std::wasm_application_io::RenderNode<_, _, _>, input: WasmEditorApi, output: RenderOutput, fn_params: [Footprint => Vec<Color>, () => Arc<WasmSurfaceHandle>]),
async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: VectorData, fn_params: [Footprint => VectorData, () => DVec2, () => f64, () => DVec2, () => DVec2, () => DVec2]),
async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: WasmSurfaceHandleFrame, fn_params: [Footprint => WasmSurfaceHandleFrame, () => DVec2, () => f64, () => DVec2, () => DVec2, () => DVec2]),
async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: WasmSurfaceHandleFrame, fn_params: [Footprint => WasmSurfaceHandleFrame, () => DVec2, () => f64, () => DVec2, () => DVec2, () => DVec2]),
async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: ImageFrame<Color>, fn_params: [Footprint => ImageFrame<Color>, () => DVec2, () => f64, () => DVec2, () => DVec2, () => DVec2]),
async_node!(graphene_core::transform::TransformNode<_, _, _, _, _, _>, input: Footprint, output: GraphicGroup, fn_params: [Footprint => GraphicGroup, () => DVec2, () => f64, () => DVec2, () => DVec2, () => DVec2]),
register_node!(graphene_core::transform::SetTransformNode<_>, input: VectorData, params: [VectorData]),
@@ -800,7 +799,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
register_node!(graphene_core::text::TextGeneratorNode<_, _, _>, input: WasmEditorApi, params: [String, graphene_core::text::Font, f64]),
register_node!(graphene_std::brush::VectorPointsNode, input: VectorData, params: []),
register_node!(graphene_core::ExtractImageFrame, input: WasmEditorApi, params: []),
async_node!(graphene_core::ConstructLayerNode<_, _>, input: Footprint, output: GraphicGroup, fn_params: [Footprint => graphene_core::GraphicElement, Footprint => GraphicGroup]),
async_node!(graphene_core::ConstructLayerNode<_, _>, input: Footprint, output: GraphicGroup, fn_params: [Footprint => GraphicGroup, Footprint => graphene_core::GraphicElement]),
register_node!(graphene_core::ToGraphicElementNode, input: graphene_core::vector::VectorData, params: []),
register_node!(graphene_core::ToGraphicElementNode, input: ImageFrame<Color>, params: []),
register_node!(graphene_core::ToGraphicElementNode, input: GraphicGroup, params: []),
@@ -810,7 +809,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
register_node!(graphene_core::ToGraphicGroupNode, input: GraphicGroup, params: []),
register_node!(graphene_core::ToGraphicGroupNode, input: Artboard, params: []),
async_node!(graphene_core::ConstructArtboardNode<_, _, _, _, _>, input: Footprint, output: Artboard, fn_params: [Footprint => GraphicGroup, () => glam::IVec2, () => glam::IVec2, () => Color, () => bool]),
async_node!(graphene_core::AddArtboardNode<_, _>, input: Footprint, output: ArtboardGroup, fn_params: [Footprint => Artboard, Footprint => ArtboardGroup]),
async_node!(graphene_core::AddArtboardNode<_, _>, input: Footprint, output: ArtboardGroup, fn_params: [Footprint => ArtboardGroup, Footprint => Artboard]),
];
let mut map: HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeConstructor>> = HashMap::new();
for (id, c, types) in node_types.into_iter().flatten() {

View File

@@ -98,7 +98,7 @@ enum Asyncness {
}
fn node_impl_impl(attr: TokenStream, item: TokenStream, asyncness: Asyncness) -> TokenStream {
//let node_name = parse_macro_input!(attr as Ident);
// let node_name = parse_macro_input!(attr as Ident);
let node = parse_macro_input!(attr as syn::PathSegment);
let function = parse_macro_input!(item as ItemFn);
@@ -202,8 +202,8 @@ fn node_impl_impl(attr: TokenStream, item: TokenStream, asyncness: Asyncness) ->
quote::quote!(#(let #parameter_mutability #parameter_idents = self.#parameter_idents.eval(());)*)
};
let mut body_with_inputs = quote::quote!(
#parameters
{#body}
#parameters
{#body}
);
if async_out {
body_with_inputs = quote::quote!(Box::pin(async move { #body_with_inputs }));
@@ -317,7 +317,7 @@ fn input_node_bounds(parameter_inputs: Vec<Type>, node_generics: Vec<GenericPara
bounds: Punctuated::from_iter([TypeParamBound::Trait(TraitBound {
paren_token: None,
modifier: syn::TraitBoundModifier::None,
lifetimes: None, //syn::parse_quote!(for<'any_input>),
lifetimes: None, // syn::parse_quote!(for<'any_input>),
path: syn::parse_quote!(#bound),
})]),
})

View File

@@ -42,7 +42,7 @@ impl<'a, I: StaticTypeSized + Sync + Pod + Send, O: StaticTypeSized + Send + Syn
async fn execute_shader<I: Pod + Send + Sync, O: Pod + Send + Sync>(device: Arc<wgpu::Device>, queue: Arc<wgpu::Queue>, shader: Vec<u32>, data: Vec<I>, entry_point: String) -> Option<Vec<O>> {
// Loads the shader from WGSL
dbg!(&shader);
//write shader to file
// write shader to file
use std::io::Write;
let mut file = std::fs::File::create("/tmp/shader.spv").unwrap();
file.write_all(bytemuck::cast_slice(&shader)).unwrap();

View File

@@ -160,7 +160,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
usage |= wgpu::BufferUsages::MAP_WRITE | wgpu::BufferUsages::COPY_SRC;
}
log::debug!("Creating storage buffer with usage {:?} and len: {}", usage, bytes.len());
log::warn!("Creating storage buffer with usage {:?} and len: {}", usage, bytes.len());
let buffer = self.context.device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: None,
contents: bytes.as_ref(),
@@ -207,7 +207,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
}
fn create_output_buffer(&self, len: usize, ty: Type, cpu_readable: bool) -> Result<WgpuShaderInput> {
log::debug!("Creating output buffer with len: {len}");
log::warn!("Creating output buffer with len: {len}");
let create_buffer = |usage| {
Ok::<_, anyhow::Error>(self.context.device.create_buffer(&BufferDescriptor {
label: None,
@@ -294,7 +294,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
println!("{surface_caps:?}");
if surface_caps.formats.is_empty() {
log::warn!("No surface formats available");
//return Ok(());
// return Ok(());
}
let Some(config) = self.surface_config.take() else { return Ok(()) };
let new_config = config.clone();
@@ -423,7 +423,7 @@ impl gpu_executor::GpuExecutor for WgpuExecutor {
}
fn create_texture_view(&self, texture: ShaderInput<Self>) -> Result<ShaderInput<Self>> {
//Ok(ShaderInput::TextureView(texture.create_view(&wgpu::TextureViewDescriptor::default()), ) )
// Ok(ShaderInput::TextureView(texture.create_view(&wgpu::TextureViewDescriptor::default()), ) )
let ShaderInput::TextureBuffer(texture, ty) = &texture else {
bail!("Tried to create a texture view from a non texture");
};