Additional Input and Math Nodes (#1369)

* Add Input Nodes and additional Math Nodes

* Add add node to node registry

* Update node-graph/gcore/src/ops.rs

Co-authored-by: Dennis Kobert <dennis@kobert.dev>

* Fix Color Input Node

Wrong input type

* Remove non Parameter variants

* Remove non Parameter variants

* Remove non Parameter variants

* Apply suggestions from code review

* mod to modulo

---------

Co-authored-by: Dennis Kobert <dennis@kobert.dev>
This commit is contained in:
Ezbaze 2023-08-08 16:31:50 +01:00 committed by GitHub
parent e32d4c29c4
commit 5c08248681
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 298 additions and 9 deletions

View file

@ -124,6 +124,33 @@ static DOCUMENT_NODE_TYPES: once_cell::sync::Lazy<Vec<DocumentNodeType>> = once_
// TODO: Dynamic node library
fn static_nodes() -> Vec<DocumentNodeType> {
vec![
DocumentNodeType {
name: "Boolean",
category: "Inputs",
identifier: NodeImplementation::proto("graphene_core::ops::IdNode"),
inputs: vec![DocumentInputType::value("Bool", TaggedValue::Bool(true), false)],
outputs: vec![DocumentOutputType::new("Out", FrontendGraphDataType::Boolean)],
properties: node_properties::boolean_properties,
..Default::default()
},
DocumentNodeType {
name: "Value",
category: "Inputs",
identifier: NodeImplementation::proto("graphene_core::ops::IdNode"),
inputs: vec![DocumentInputType::value("Value", TaggedValue::F32(0.), false)],
outputs: vec![DocumentOutputType::new("Out", FrontendGraphDataType::Number)],
properties: node_properties::value_properties,
..Default::default()
},
DocumentNodeType {
name: "Color",
category: "Inputs",
identifier: NodeImplementation::proto("graphene_core::ops::IdNode"),
inputs: vec![DocumentInputType::value("Value", TaggedValue::OptionalColor(None), false)],
outputs: vec![DocumentOutputType::new("Out", FrontendGraphDataType::Color)],
properties: node_properties::color_properties,
..Default::default()
},
DocumentNodeType {
name: "Identity",
category: "Structural",
@ -665,6 +692,24 @@ fn static_nodes() -> Vec<DocumentNodeType> {
properties: node_properties::grayscale_properties,
..Default::default()
},
DocumentNodeType {
name: "Color Channel",
category: "Image Adjustments",
identifier: NodeImplementation::proto("graphene_core::ops::IdNode"),
inputs: vec![DocumentInputType::value("Channel", TaggedValue::RedGreenBlue(RedGreenBlue::Red), false)],
outputs: vec![DocumentOutputType::new("Out", FrontendGraphDataType::General)],
properties: node_properties::color_channel_properties,
..Default::default()
},
DocumentNodeType {
name: "Blend Mode",
category: "Image Adjustments",
identifier: NodeImplementation::proto("graphene_core::ops::IdNode"),
inputs: vec![DocumentInputType::value("Mode", TaggedValue::BlendMode(BlendMode::Normal), false)],
outputs: vec![DocumentOutputType::new("Out", FrontendGraphDataType::General)],
properties: node_properties::blend_mode_properties,
..Default::default()
},
DocumentNodeType {
name: "Luminance",
category: "Image Adjustments",
@ -1645,13 +1690,73 @@ fn static_nodes() -> Vec<DocumentNodeType> {
category: "Math",
identifier: NodeImplementation::proto("graphene_core::ops::AddParameterNode<_>"),
inputs: vec![
DocumentInputType::value("Input", TaggedValue::F32(0.), true),
DocumentInputType::value("Addend", TaggedValue::F32(0.), true),
DocumentInputType::value("Primary", TaggedValue::F32(0.), true),
DocumentInputType::value("Addend", TaggedValue::F32(0.), false),
],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::add_properties,
..Default::default()
},
DocumentNodeType {
name: "Subtract",
category: "Math",
identifier: NodeImplementation::proto("graphene_core::ops::AddParameterNode<_>"),
inputs: vec![
DocumentInputType::value("Primary", TaggedValue::F32(0.), true),
DocumentInputType::value("Subtrahend", TaggedValue::F32(0.), false),
],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::subtract_properties,
..Default::default()
},
DocumentNodeType {
name: "Divide",
category: "Math",
identifier: NodeImplementation::proto("graphene_core::ops::DivideParameterNode<_>"),
inputs: vec![
DocumentInputType::value("Primary", TaggedValue::F32(0.), true),
DocumentInputType::value("Divisor", TaggedValue::F32(0.), false),
],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::divide_properties,
..Default::default()
},
DocumentNodeType {
name: "Multiply",
category: "Math",
identifier: NodeImplementation::proto("graphene_core::ops::MultiplyParameterNode<_>"),
inputs: vec![
DocumentInputType::value("Primary", TaggedValue::F32(0.), true),
DocumentInputType::value("Multiplicand", TaggedValue::F32(0.), false),
],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::multiply_properties,
..Default::default()
},
DocumentNodeType {
name: "Exponent",
category: "Math",
identifier: NodeImplementation::proto("graphene_core::ops::ExponentParameterNode<_>"),
inputs: vec![
DocumentInputType::value("Primary", TaggedValue::F32(0.), true),
DocumentInputType::value("Power", TaggedValue::F32(0.), false),
],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::exponent_properties,
..Default::default()
},
DocumentNodeType {
name: "Modulo",
category: "Math",
identifier: NodeImplementation::proto("graphene_core::ops::ModuloParameterNode<_>"),
inputs: vec![
DocumentInputType::value("Primary", TaggedValue::F32(0.), true),
DocumentInputType::value("Modulus", TaggedValue::F32(0.), false),
],
outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)],
properties: node_properties::modulo_properties,
..Default::default()
},
(*IMAGINATE_NODE).clone(),
DocumentNodeType {
name: "Unit Circle Generator",

View file

@ -639,6 +639,33 @@ pub fn blend_properties(document_node: &DocumentNode, node_id: NodeId, _context:
vec![backdrop, blend_mode, LayoutGroup::Row { widgets: opacity }]
}
pub fn value_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let operand = |name: &str, index| {
let widgets = number_widget(document_node, node_id, index, name, NumberInput::default(), true);
LayoutGroup::Row { widgets }
};
vec![operand("Value", 0)]
}
pub fn boolean_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let operand = |name: &str, index| {
let widgets = bool_widget(document_node, node_id, index, name, true);
LayoutGroup::Row { widgets }
};
vec![operand("Bool", 0)]
}
pub fn color_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let operand = |name: &str, index| {
let color = color_widget(document_node, node_id, index, name, ColorInput::default(), true);
color
};
vec![operand("Color", 0)]
}
pub fn load_image_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let url = text_widget(document_node, node_id, 1, "Url", true);
@ -682,6 +709,24 @@ pub fn mask_properties(document_node: &DocumentNode, node_id: NodeId, _context:
vec![mask]
}
pub fn blend_mode_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let operand = |name: &str, index| {
let blend_mode = blend_mode(document_node, node_id, index, name, true);
blend_mode
};
vec![operand("Blend Mode", 0)]
}
pub fn color_channel_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let operand = |name: &str, index| {
let color_channel = color_channel(document_node, node_id, index, name, true);
color_channel
};
vec![operand("Channel", 0)]
}
pub fn luminance_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let luminance_calc = luminance_calculation(document_node, node_id, 1, "Luminance Calc", true);
@ -938,7 +983,52 @@ pub fn add_properties(document_node: &DocumentNode, node_id: NodeId, _context: &
LayoutGroup::Row { widgets }
};
vec![operand("Input", 0), operand("Addend", 1)]
vec![operand("Addend", 1)]
}
pub fn subtract_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let operand = |name: &str, index| {
let widgets = number_widget(document_node, node_id, index, name, NumberInput::default(), true);
LayoutGroup::Row { widgets }
};
vec![operand("Subtrahend", 1)]
}
pub fn divide_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let operand = |name: &str, index| {
let widgets = number_widget(document_node, node_id, index, name, NumberInput::default(), true);
LayoutGroup::Row { widgets }
};
vec![operand("Divisor", 1)]
}
pub fn multiply_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let operand = |name: &str, index| {
let widgets = number_widget(document_node, node_id, index, name, NumberInput::default(), true);
LayoutGroup::Row { widgets }
};
vec![operand("Multiplicand", 1)]
}
pub fn exponent_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let operand = |name: &str, index| {
let widgets = number_widget(document_node, node_id, index, name, NumberInput::default(), true);
LayoutGroup::Row { widgets }
};
vec![operand("Power", 1)]
}
pub fn modulo_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {
let operand = |name: &str, index| {
let widgets = number_widget(document_node, node_id, index, name, NumberInput::default(), true);
LayoutGroup::Row { widgets }
};
vec![operand("Modulo", 1)]
}
pub fn transform_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec<LayoutGroup> {

View file

@ -1,8 +1,9 @@
use core::marker::PhantomData;
use core::ops::{Add, Mul};
use crate::Node;
use core::marker::PhantomData;
use core::ops::{Add, Div, Mul, Rem, Sub};
use num_traits::Pow;
// Add
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
pub struct AddNode;
@ -30,18 +31,71 @@ where
first + second
}
pub struct MulParameterNode<Second> {
// Subtract
pub struct SubtractParameterNode<Second> {
second: Second,
}
#[node_macro::node_fn(MulParameterNode)]
fn flat_map<U, T>(first: U, second: T) -> <U as Mul<T>>::Output
#[node_macro::node_fn(SubtractParameterNode)]
fn sub<U, T>(first: U, second: T) -> <U as Sub<T>>::Output
where
U: Sub<T>,
{
first - second
}
// Divide
pub struct DivideParameterNode<Second> {
second: Second,
}
#[node_macro::node_fn(DivideParameterNode)]
fn div<U, T>(first: U, second: T) -> <U as Div<T>>::Output
where
U: Div<T>,
{
first / second
}
// Multiply
pub struct MultiplyParameterNode<Second> {
second: Second,
}
#[node_macro::node_fn(MultiplyParameterNode)]
fn mul<U, T>(first: U, second: T) -> <U as Mul<T>>::Output
where
U: Mul<T>,
{
first * second
}
// Exponent
pub struct ExponentParameterNode<Second> {
second: Second,
}
#[node_macro::node_fn(ExponentParameterNode)]
fn exp<U, T>(first: U, second: T) -> <U as Pow<T>>::Output
where
U: Pow<T>,
{
first.pow(second)
}
// Modulo
pub struct ModuloParameterNode<Second> {
second: Second,
}
#[node_macro::node_fn(ModuloParameterNode)]
fn modulo<U, T>(first: U, second: T) -> <U as Rem<T>>::Output
where
U: Rem<T>,
{
first % second
}
#[cfg(feature = "std")]
struct SizeOfNode {}

View file

@ -196,6 +196,46 @@ fn node_registry() -> HashMap<NodeIdentifier, HashMap<NodeIOTypes, NodeConstruct
register_node!(graphene_core::ops::AddParameterNode<_>, input: &f32, params: [f32]),
register_node!(graphene_core::ops::AddParameterNode<_>, input: f32, params: [&f32]),
register_node!(graphene_core::ops::AddParameterNode<_>, input: &f32, params: [&f32]),
register_node!(graphene_core::ops::SubtractParameterNode<_>, input: u32, params: [u32]),
register_node!(graphene_core::ops::SubtractParameterNode<_>, input: &u32, params: [u32]),
register_node!(graphene_core::ops::SubtractParameterNode<_>, input: u32, params: [&u32]),
register_node!(graphene_core::ops::SubtractParameterNode<_>, input: &u32, params: [&u32]),
register_node!(graphene_core::ops::SubtractParameterNode<_>, input: f32, params: [f32]),
register_node!(graphene_core::ops::SubtractParameterNode<_>, input: &f32, params: [f32]),
register_node!(graphene_core::ops::SubtractParameterNode<_>, input: f32, params: [&f32]),
register_node!(graphene_core::ops::SubtractParameterNode<_>, input: &f32, params: [&f32]),
register_node!(graphene_core::ops::DivideParameterNode<_>, input: u32, params: [u32]),
register_node!(graphene_core::ops::DivideParameterNode<_>, input: &u32, params: [u32]),
register_node!(graphene_core::ops::DivideParameterNode<_>, input: u32, params: [&u32]),
register_node!(graphene_core::ops::DivideParameterNode<_>, input: &u32, params: [&u32]),
register_node!(graphene_core::ops::DivideParameterNode<_>, input: f32, params: [f32]),
register_node!(graphene_core::ops::DivideParameterNode<_>, input: &f32, params: [f32]),
register_node!(graphene_core::ops::DivideParameterNode<_>, input: f32, params: [&f32]),
register_node!(graphene_core::ops::DivideParameterNode<_>, input: &f32, params: [&f32]),
register_node!(graphene_core::ops::MultiplyParameterNode<_>, input: u32, params: [u32]),
register_node!(graphene_core::ops::MultiplyParameterNode<_>, input: &u32, params: [u32]),
register_node!(graphene_core::ops::MultiplyParameterNode<_>, input: u32, params: [&u32]),
register_node!(graphene_core::ops::MultiplyParameterNode<_>, input: &u32, params: [&u32]),
register_node!(graphene_core::ops::MultiplyParameterNode<_>, input: f32, params: [f32]),
register_node!(graphene_core::ops::MultiplyParameterNode<_>, input: &f32, params: [f32]),
register_node!(graphene_core::ops::MultiplyParameterNode<_>, input: f32, params: [&f32]),
register_node!(graphene_core::ops::MultiplyParameterNode<_>, input: &f32, params: [&f32]),
register_node!(graphene_core::ops::ExponentParameterNode<_>, input: u32, params: [u32]),
register_node!(graphene_core::ops::ExponentParameterNode<_>, input: &u32, params: [u32]),
register_node!(graphene_core::ops::ExponentParameterNode<_>, input: u32, params: [&u32]),
register_node!(graphene_core::ops::ExponentParameterNode<_>, input: &u32, params: [&u32]),
register_node!(graphene_core::ops::ExponentParameterNode<_>, input: f32, params: [f32]),
register_node!(graphene_core::ops::ExponentParameterNode<_>, input: &f32, params: [f32]),
register_node!(graphene_core::ops::ExponentParameterNode<_>, input: f32, params: [&f32]),
register_node!(graphene_core::ops::ExponentParameterNode<_>, input: &f32, params: [&f32]),
register_node!(graphene_core::ops::ModuloParameterNode<_>, input: u32, params: [u32]),
register_node!(graphene_core::ops::ModuloParameterNode<_>, input: &u32, params: [u32]),
register_node!(graphene_core::ops::ModuloParameterNode<_>, input: u32, params: [&u32]),
register_node!(graphene_core::ops::ModuloParameterNode<_>, input: &u32, params: [&u32]),
register_node!(graphene_core::ops::ModuloParameterNode<_>, input: f32, params: [f32]),
register_node!(graphene_core::ops::ModuloParameterNode<_>, input: &f32, params: [f32]),
register_node!(graphene_core::ops::ModuloParameterNode<_>, input: f32, params: [&f32]),
register_node!(graphene_core::ops::ModuloParameterNode<_>, input: &f32, params: [&f32]),
register_node!(graphene_core::ops::SomeNode, input: WasmEditorApi, params: []),
async_node!(graphene_core::ops::IntoNode<_, ImageFrame<SRGBA8>>, input: ImageFrame<Color>, output: ImageFrame<SRGBA8>, params: []),
async_node!(graphene_core::ops::IntoNode<_, ImageFrame<Color>>, input: ImageFrame<SRGBA8>, output: ImageFrame<Color>, params: []),