From 3419e739af7b199b4f81afffe60987781c5dbac5 Mon Sep 17 00:00:00 2001 From: isiko Date: Wed, 30 Aug 2023 08:55:14 +0200 Subject: [PATCH] New nodes: Logical boolean operations (OR, AND, XOR, NOT) (#1399) * Add Boolean Operations Nodes Adds OR AND XOR and NOT operators * Fix operand naming Inputs to the 'Min' 'Max' 'Equality' and boolean operations nodes were previously named 'First' and 'Second' and are now called 'Operand A' and 'Operand B' * Rename Equality to Equals --------- Co-authored-by: Keavon Chambers --- .../document_node_types.rs | 61 ++++++++++++++++--- .../node_properties.rs | 7 ++- node-graph/gcore/src/logic.rs | 34 +++++++++++ node-graph/gcore/src/ops.rs | 2 +- .../interpreted-executor/src/node_registry.rs | 4 ++ 5 files changed, 98 insertions(+), 10 deletions(-) diff --git a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/document_node_types.rs b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/document_node_types.rs index f3d360e9..265219c6 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/document_node_types.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/document_node_types.rs @@ -1861,8 +1861,8 @@ fn static_nodes() -> Vec { category: "Math", identifier: NodeImplementation::proto("graphene_core::ops::MaxParameterNode<_>"), inputs: vec![ - DocumentInputType::value("First", TaggedValue::F32(0.), true), - DocumentInputType::value("Second", TaggedValue::F32(0.), true), + DocumentInputType::value("Operand A", TaggedValue::F32(0.), true), + DocumentInputType::value("Operand B", TaggedValue::F32(0.), true), ], outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)], properties: node_properties::max_properties, @@ -1873,20 +1873,20 @@ fn static_nodes() -> Vec { category: "Math", identifier: NodeImplementation::proto("graphene_core::ops::MinParameterNode<_>"), inputs: vec![ - DocumentInputType::value("First", TaggedValue::F32(0.), true), - DocumentInputType::value("Second", TaggedValue::F32(0.), true), + DocumentInputType::value("Operand A", TaggedValue::F32(0.), true), + DocumentInputType::value("Operand B", TaggedValue::F32(0.), true), ], outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)], properties: node_properties::min_properties, ..Default::default() }, DocumentNodeType { - name: "Equality", + name: "Equals", category: "Math", identifier: NodeImplementation::proto("graphene_core::ops::EqParameterNode<_>"), inputs: vec![ - DocumentInputType::value("First", TaggedValue::F32(0.), true), - DocumentInputType::value("Second", TaggedValue::F32(0.), true), + DocumentInputType::value("Operand A", TaggedValue::F32(0.), true), + DocumentInputType::value("Operand B", TaggedValue::F32(0.), true), ], outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Number)], properties: node_properties::eq_properties, @@ -1908,11 +1908,56 @@ fn static_nodes() -> Vec { name: "Log to Console", category: "Logic", identifier: NodeImplementation::proto("graphene_core::logic::LogToConsoleNode"), - inputs: vec![DocumentInputType::value("First", TaggedValue::String("Not Connected to a value yet".into()), true)], + inputs: vec![DocumentInputType::value("Input", TaggedValue::String("Not Connected to a value yet".into()), true)], outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::General)], properties: node_properties::no_properties, ..Default::default() }, + DocumentNodeType { + name: "Or", + category: "Logic", + identifier: NodeImplementation::proto("graphene_core::logic::LogicOrNode<_>"), + inputs: vec![ + DocumentInputType::value("Operand A", TaggedValue::Bool(false), true), + DocumentInputType::value("Operand B", TaggedValue::Bool(false), true), + ], + outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Boolean)], + properties: node_properties::logic_operator_properties, + ..Default::default() + }, + DocumentNodeType { + name: "And", + category: "Logic", + identifier: NodeImplementation::proto("graphene_core::logic::LogicAndNode<_>"), + inputs: vec![ + DocumentInputType::value("Operand A", TaggedValue::Bool(false), true), + DocumentInputType::value("Operand B", TaggedValue::Bool(false), true), + ], + outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Boolean)], + properties: node_properties::logic_operator_properties, + ..Default::default() + }, + DocumentNodeType { + name: "XOR", + category: "Logic", + identifier: NodeImplementation::proto("graphene_core::logic::LogicXorNode<_>"), + inputs: vec![ + DocumentInputType::value("Operand A", TaggedValue::Bool(false), true), + DocumentInputType::value("Operand B", TaggedValue::Bool(false), true), + ], + outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Boolean)], + properties: node_properties::logic_operator_properties, + ..Default::default() + }, + DocumentNodeType { + name: "Not", + category: "Logic", + identifier: NodeImplementation::proto("graphene_core::logic::LogicNotNode"), + inputs: vec![DocumentInputType::value("Input", TaggedValue::Bool(false), true)], + outputs: vec![DocumentOutputType::new("Output", FrontendGraphDataType::Boolean)], + properties: node_properties::no_properties, + ..Default::default() + }, (*IMAGINATE_NODE).clone(), DocumentNodeType { name: "Circle", diff --git a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/node_properties.rs b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/node_properties.rs index 7cb2829f..8c3e929f 100644 --- a/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/node_properties.rs +++ b/editor/src/messages/portfolio/document/node_graph/node_graph_message_handler/node_properties.rs @@ -1145,7 +1145,7 @@ pub fn eq_properties(document_node: &DocumentNode, node_id: NodeId, _context: &m LayoutGroup::Row { widgets } }; - vec![operand("Equality", 1)] + vec![operand("Equals", 1)] } pub fn modulo_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec { @@ -1206,6 +1206,11 @@ pub fn spline_properties(document_node: &DocumentNode, node_id: NodeId, _context }] } +pub fn logic_operator_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec { + let widgets = bool_widget(document_node, node_id, 0, "Operand B", true); + vec![LayoutGroup::Row { widgets }] +} + pub fn transform_properties(document_node: &DocumentNode, node_id: NodeId, _context: &mut NodePropertiesContext) -> Vec { let translation_assist = |widgets: &mut Vec| { let pivot_index = 5; diff --git a/node-graph/gcore/src/logic.rs b/node-graph/gcore/src/logic.rs index 2d56e313..88619ae6 100644 --- a/node-graph/gcore/src/logic.rs +++ b/node-graph/gcore/src/logic.rs @@ -7,3 +7,37 @@ fn log_to_console(value: T) -> T { debug!("{:#?}", value); value } + +pub struct LogicOrNode { + second: Second, +} + +#[node_macro::node_fn(LogicOrNode)] +fn logic_or(first: bool, second: bool) -> bool { + first || second +} + +pub struct LogicAndNode { + second: Second, +} + +#[node_macro::node_fn(LogicAndNode)] +fn logic_and(first: bool, second: bool) -> bool { + first && second +} + +pub struct LogicXorNode { + second: Second, +} + +#[node_macro::node_fn(LogicXorNode)] +fn logic_xor(first: bool, second: bool) -> bool { + first ^ second +} + +pub struct LogicNotNode; + +#[node_macro::node_fn(LogicNotNode)] +fn logic_not(first: bool) -> bool { + !first +} diff --git a/node-graph/gcore/src/ops.rs b/node-graph/gcore/src/ops.rs index b78e871b..e01b8883 100644 --- a/node-graph/gcore/src/ops.rs +++ b/node-graph/gcore/src/ops.rs @@ -183,7 +183,7 @@ fn max(first: T, second: T) -> T { } } -// Equality +// Equals pub struct EqParameterNode { second: Second, } diff --git a/node-graph/interpreted-executor/src/node_registry.rs b/node-graph/interpreted-executor/src/node_registry.rs index 510c37cb..662714f7 100644 --- a/node-graph/interpreted-executor/src/node_registry.rs +++ b/node-graph/interpreted-executor/src/node_registry.rs @@ -260,6 +260,10 @@ fn node_registry() -> HashMap, input: bool, params: [bool]), + register_node!(graphene_core::logic::LogicAndNode<_>, input: bool, params: [bool]), + register_node!(graphene_core::logic::LogicXorNode<_>, input: bool, params: [bool]), + register_node!(graphene_core::logic::LogicNotNode, input: bool, params: []), async_node!(graphene_core::ops::IntoNode<_, ImageFrame>, input: ImageFrame, output: ImageFrame, params: []), async_node!(graphene_core::ops::IntoNode<_, ImageFrame>, input: ImageFrame, output: ImageFrame, params: []), #[cfg(feature = "gpu")]