mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
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:
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)";
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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] {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -536,7 +536,6 @@ impl ProtoNetwork {
|
||||
}
|
||||
}
|
||||
}
|
||||
debug!("Sorted order {sorted:?}");
|
||||
sorted
|
||||
}*/
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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), ()));
|
||||
|
||||
@@ -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()
|
||||
},
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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),
|
||||
})]),
|
||||
})
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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");
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user