Simulations: Add Boolean Math, Switch and Float Compare node UI
authorJacques Lucke <jacques@blender.org>
Mon, 20 Apr 2020 13:27:12 +0000 (15:27 +0200)
committerJacques Lucke <jacques@blender.org>
Mon, 20 Apr 2020 13:27:58 +0000 (15:27 +0200)
Reviewers: brecht

Differential Revision: https://developer.blender.org/D7424

16 files changed:
release/scripts/startup/nodeitems_builtins.py
source/blender/blenkernel/BKE_node.h
source/blender/blenkernel/intern/node.c
source/blender/editors/space_node/drawnode.c
source/blender/makesdna/DNA_node_types.h
source/blender/makesrna/RNA_access.h
source/blender/makesrna/RNA_enum_types.h
source/blender/makesrna/intern/rna_nodetree.c
source/blender/nodes/CMakeLists.txt
source/blender/nodes/NOD_function.h [new file with mode: 0644]
source/blender/nodes/NOD_static_types.h
source/blender/nodes/function/node_function_util.cc [new file with mode: 0644]
source/blender/nodes/function/node_function_util.h [new file with mode: 0644]
source/blender/nodes/function/nodes/node_fn_boolean_math.cc [new file with mode: 0644]
source/blender/nodes/function/nodes/node_fn_float_compare.cc [new file with mode: 0644]
source/blender/nodes/function/nodes/node_fn_switch.cc [new file with mode: 0644]

index fd601035288201a897bcf666426b0b5a788c2eb1..fd169027c76c71579ab50e76d97d616039dac0f9 100644 (file)
@@ -524,6 +524,9 @@ simulation_node_categories = [
         NodeItem("ShaderNodeCombineXYZ"),
         NodeItem("ShaderNodeSeparateHSV"),
         NodeItem("ShaderNodeCombineHSV"),
+        NodeItem("FunctionNodeBooleanMath"),
+        NodeItem("FunctionNodeFloatCompare"),
+        NodeItem("FunctionNodeSwitch"),
     ]),
     SimulationNodeCategory("SIM_GROUP", "Group", items=node_group_items),
     SimulationNodeCategory("SIM_LAYOUT", "Layout", items=[
index 38bf3d828f73e5d02809f22091c18809cc08b250..ea2a84f14f99bf1a5ca9494d21054d00dc131386 100644 (file)
@@ -1302,6 +1302,16 @@ int ntreeTexExecTree(struct bNodeTree *ntree,
 
 /** \} */
 
+/* -------------------------------------------------------------------- */
+/** \name Function Nodes
+ * \{ */
+
+#define FN_NODE_BOOLEAN_MATH 1200
+#define FN_NODE_SWITCH 1201
+#define FN_NODE_FLOAT_COMPARE 1202
+
+/** \} */
+
 void init_nodesystem(void);
 void free_nodesystem(void);
 
index 2237d061fe11f5cd231fe1572fa1e59dcbca79a6..6c67ff14dacc8edca192a0b658cd017ab5bb1432 100644 (file)
@@ -67,6 +67,7 @@
 
 #include "NOD_common.h"
 #include "NOD_composite.h"
+#include "NOD_function.h"
 #include "NOD_shader.h"
 #include "NOD_simulation.h"
 #include "NOD_socket.h"
@@ -4242,6 +4243,13 @@ static void registerSimulationNodes(void)
   register_node_type_sim_particle_attribute();
 }
 
+static void registerFunctionNodes(void)
+{
+  register_node_type_fn_boolean_math();
+  register_node_type_fn_float_compare();
+  register_node_type_fn_switch();
+}
+
 void init_nodesystem(void)
 {
   nodetreetypes_hash = BLI_ghash_str_new("nodetreetypes_hash gh");
@@ -4266,6 +4274,7 @@ void init_nodesystem(void)
   registerShaderNodes();
   registerTextureNodes();
   registerSimulationNodes();
+  registerFunctionNodes();
 }
 
 void free_nodesystem(void)
index 4670f0fc6f645f5a78f198ad307ed675985becf0..70f3db1e2ab0e0656bd71f5802e5383426d6e3cc 100644 (file)
@@ -3179,6 +3179,40 @@ static void node_simulation_set_butfunc(bNodeType *ntype)
   }
 }
 
+/* ****************** BUTTON CALLBACKS FOR FUNCTION NODES ***************** */
+
+static void node_function_buts_boolean_math(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+  uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
+}
+
+static void node_function_buts_float_compare(uiLayout *layout,
+                                             bContext *UNUSED(C),
+                                             PointerRNA *ptr)
+{
+  uiItemR(layout, ptr, "operation", 0, "", ICON_NONE);
+}
+
+static void node_function_buts_switch(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+  uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
+}
+
+static void node_function_set_butfunc(bNodeType *ntype)
+{
+  switch (ntype->type) {
+    case FN_NODE_BOOLEAN_MATH:
+      ntype->draw_buttons = node_function_buts_boolean_math;
+      break;
+    case FN_NODE_FLOAT_COMPARE:
+      ntype->draw_buttons = node_function_buts_float_compare;
+      break;
+    case FN_NODE_SWITCH:
+      ntype->draw_buttons = node_function_buts_switch;
+      break;
+  }
+}
+
 /* ****** init draw callbacks for all tree types, only called in usiblender.c, once ************ */
 
 static void node_property_update_default(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
@@ -3288,6 +3322,7 @@ void ED_node_init_butfuncs(void)
     node_shader_set_butfunc(ntype);
     node_texture_set_butfunc(ntype);
     node_simulation_set_butfunc(ntype);
+    node_function_set_butfunc(ntype);
 
     /* define update callbacks for socket properties */
     node_template_properties_update(ntype);
index 81911116b66ed968b3373f4ceb8e9a7839a65997..4ff0e531168862c1dde1d75bf1c54b56102f2381 100644 (file)
@@ -1308,6 +1308,23 @@ enum {
   NODE_VECTOR_MATH_TANGENT = 23,
 };
 
+/* Boolean math node operations. */
+enum {
+  NODE_BOOLEAN_MATH_AND = 0,
+  NODE_BOOLEAN_MATH_OR = 1,
+  NODE_BOOLEAN_MATH_NOT = 2,
+};
+
+/* Float compare node operations. */
+enum {
+  NODE_FLOAT_COMPARE_LESS_THAN = 0,
+  NODE_FLOAT_COMPARE_LESS_EQUAL = 1,
+  NODE_FLOAT_COMPARE_GREATER_THAN = 2,
+  NODE_FLOAT_COMPARE_GREATER_EQUAL = 3,
+  NODE_FLOAT_COMPARE_EQUAL = 4,
+  NODE_FLOAT_COMPARE_NOT_EQUAL = 5,
+};
+
 /* Clamp node types. */
 enum {
   NODE_CLAMP_MINMAX = 0,
index a77d07dfe17d17516d178f7cd4b2bf1a265e2c2c..d2e27bdbcad8a24ff966fba49b169bd5a0130b41 100644 (file)
@@ -259,6 +259,7 @@ extern StructRNA RNA_FreestyleLineStyle;
 extern StructRNA RNA_FreestyleModuleSettings;
 extern StructRNA RNA_FreestyleSettings;
 extern StructRNA RNA_Function;
+extern StructRNA RNA_FunctionNode;
 extern StructRNA RNA_GPencilFrame;
 extern StructRNA RNA_GPencilInterpolateSettings;
 extern StructRNA RNA_GPencilLayer;
index fef98f9da4b9d27a6dbb3edf399a8bddb399f8e6..b2f9c90b7f5ff150613e23d73ead227c21a1fab1 100644 (file)
@@ -191,6 +191,8 @@ extern const EnumPropertyItem rna_enum_node_socket_in_out_items[];
 extern const EnumPropertyItem rna_enum_node_math_items[];
 extern const EnumPropertyItem rna_enum_mapping_type_items[];
 extern const EnumPropertyItem rna_enum_node_vec_math_items[];
+extern const EnumPropertyItem rna_enum_node_boolean_math_items[];
+extern const EnumPropertyItem rna_enum_node_float_compare_items[];
 extern const EnumPropertyItem rna_enum_node_filter_items[];
 extern const EnumPropertyItem rna_enum_node_map_range_items[];
 extern const EnumPropertyItem rna_enum_node_clamp_items[];
index 0c4583983a80d21596f887b06af58229e8c0da2d..9242ad7237fba603db9b4c9dcfc0bec52d3f8fee 100644 (file)
@@ -101,6 +101,18 @@ static const EnumPropertyItem particle_attribute_socket_type_items[] = {
     {0, NULL, 0, NULL, NULL},
 };
 
+static const EnumPropertyItem node_socket_data_type_items[] = {
+    {SOCK_FLOAT, "FLOAT", 0, "Float", ""},
+    {SOCK_INT, "INT", 0, "Int", ""},
+    {SOCK_BOOLEAN, "BOOLEAN", 0, "Boolean", ""},
+    {SOCK_VECTOR, "VECTOR", 0, "Vector", ""},
+    {SOCK_STRING, "STRING", 0, "String", ""},
+    {SOCK_RGBA, "RGBA", 0, "Color", ""},
+    {SOCK_OBJECT, "OBJECT", 0, "Object", ""},
+    {SOCK_IMAGE, "IMAGE", 0, "Image", ""},
+    {0, NULL, 0, NULL, NULL},
+};
+
 static const EnumPropertyItem node_quality_items[] = {
     {NTREE_QUALITY_HIGH, "HIGH", 0, "High", "High quality"},
     {NTREE_QUALITY_MEDIUM, "MEDIUM", 0, "Medium", "Medium quality"},
@@ -261,6 +273,47 @@ const EnumPropertyItem rna_enum_node_vec_math_items[] = {
     {0, NULL, 0, NULL, NULL},
 };
 
+const EnumPropertyItem rna_enum_node_boolean_math_items[] = {
+    {NODE_BOOLEAN_MATH_AND, "AND", 0, "And", "Outputs true only when both inputs are true"},
+    {NODE_BOOLEAN_MATH_OR, "OR", 0, "Or", "Outputs or when at least one of the inputs is true"},
+    {NODE_BOOLEAN_MATH_NOT, "NOT", 0, "Not", "Outputs the opposite of the input"},
+    {0, NULL, 0, NULL, NULL},
+};
+
+const EnumPropertyItem rna_enum_node_float_compare_items[] = {
+    {NODE_FLOAT_COMPARE_LESS_THAN,
+     "LESS_THAN",
+     0,
+     "A < B",
+     "True when the first input is smaller than second input"},
+    {NODE_FLOAT_COMPARE_LESS_EQUAL,
+     "LESS_EQUAL",
+     0,
+     "A <= B",
+     "True when the first input is smaller than the second input or equal"},
+    {NODE_FLOAT_COMPARE_GREATER_THAN,
+     "GREATER_THAN",
+     0,
+     "A > B",
+     "True when the first input is greater than the second input"},
+    {NODE_FLOAT_COMPARE_GREATER_EQUAL,
+     "GREATER_EQUAL",
+     0,
+     "A >= B",
+     "True when the first input is greater than the second input or equal"},
+    {NODE_FLOAT_COMPARE_EQUAL,
+     "EQUAL",
+     0,
+     "A = B",
+     "True when both inputs are approximately equal"},
+    {NODE_FLOAT_COMPARE_NOT_EQUAL,
+     "NOT_EQUAL",
+     0,
+     "A != B",
+     "True when both inputs are not approximately equal"},
+    {0, NULL, 0, NULL, NULL},
+};
+
 const EnumPropertyItem rna_enum_node_map_range_items[] = {
     {NODE_MAP_RANGE_LINEAR,
      "LINEAR",
@@ -700,6 +753,20 @@ static const EnumPropertyItem *rna_node_static_type_itemf(bContext *UNUSED(C),
 #  undef DefNode
   }
 
+  if (RNA_struct_is_a(ptr->type, &RNA_FunctionNode)) {
+#  define DefNode(Category, ID, DefFunc, EnumName, StructName, UIName, UIDesc) \
+    if (STREQ(#Category, "FunctionNode")) { \
+      tmp.value = ID; \
+      tmp.identifier = EnumName; \
+      tmp.name = UIName; \
+      tmp.description = UIDesc; \
+      tmp.icon = ICON_NONE; \
+      RNA_enum_item_add(&item, &totitem, &tmp); \
+    }
+#  include "../../nodes/NOD_static_types.h"
+#  undef DefNode
+  }
+
   RNA_enum_item_end(&item, &totitem);
   *r_free = true;
 
@@ -1838,6 +1905,28 @@ static StructRNA *rna_SimulationNode_register(Main *bmain,
   return nt->rna_ext.srna;
 }
 
+static StructRNA *rna_FunctionNode_register(Main *bmain,
+                                            ReportList *reports,
+                                            void *data,
+                                            const char *identifier,
+                                            StructValidateFunc validate,
+                                            StructCallbackFunc call,
+                                            StructFreeFunc free)
+{
+  bNodeType *nt = rna_Node_register_base(
+      bmain, reports, &RNA_FunctionNode, data, identifier, validate, call, free);
+  if (!nt) {
+    return NULL;
+  }
+
+  nodeRegisterType(nt);
+
+  /* update while blender is running */
+  WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
+
+  return nt->rna_ext.srna;
+}
+
 static IDProperty *rna_Node_idprops(PointerRNA *ptr, bool create)
 {
   bNode *node = ptr->data;
@@ -3634,6 +3723,15 @@ static void rna_ShaderNode_socket_update(Main *bmain, Scene *scene, PointerRNA *
   rna_Node_update(bmain, scene, ptr);
 }
 
+static void rna_FunctionNode_socket_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+  bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
+  bNode *node = (bNode *)ptr->data;
+
+  nodeUpdate(ntree, node);
+  rna_Node_update(bmain, scene, ptr);
+}
+
 static void rna_CompositorNodeScale_update(Main *bmain, Scene *scene, PointerRNA *ptr)
 {
   bNodeTree *ntree = (bNodeTree *)ptr->owner_id;
@@ -4078,6 +4176,39 @@ static void def_math(StructRNA *srna)
   RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
 }
 
+static void def_boolean_math(StructRNA *srna)
+{
+  PropertyRNA *prop;
+
+  prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
+  RNA_def_property_enum_sdna(prop, NULL, "custom1");
+  RNA_def_property_enum_items(prop, rna_enum_node_boolean_math_items);
+  RNA_def_property_ui_text(prop, "Operation", "");
+  RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_FunctionNode_socket_update");
+}
+
+static void def_float_compare(StructRNA *srna)
+{
+  PropertyRNA *prop;
+
+  prop = RNA_def_property(srna, "operation", PROP_ENUM, PROP_NONE);
+  RNA_def_property_enum_sdna(prop, NULL, "custom1");
+  RNA_def_property_enum_items(prop, rna_enum_node_float_compare_items);
+  RNA_def_property_ui_text(prop, "Operation", "");
+  RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_FunctionNode_socket_update");
+}
+
+static void def_fn_switch(StructRNA *srna)
+{
+  PropertyRNA *prop;
+
+  prop = RNA_def_property(srna, "data_type", PROP_ENUM, PROP_NONE);
+  RNA_def_property_enum_sdna(prop, NULL, "custom1");
+  RNA_def_property_enum_items(prop, node_socket_data_type_items);
+  RNA_def_property_ui_text(prop, "Data Type", "Data type for inputs and outputs");
+  RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_FunctionNode_socket_update");
+}
+
 static void def_vector_math(StructRNA *srna)
 {
   PropertyRNA *prop;
@@ -8084,6 +8215,16 @@ static void rna_def_simulation_node(BlenderRNA *brna)
   RNA_def_struct_register_funcs(srna, "rna_SimulationNode_register", "rna_Node_unregister", NULL);
 }
 
+static void rna_def_function_node(BlenderRNA *brna)
+{
+  StructRNA *srna;
+
+  srna = RNA_def_struct(brna, "FunctionNode", "NodeInternal");
+  RNA_def_struct_ui_text(srna, "Function Node", "");
+  RNA_def_struct_sdna(srna, "bNode");
+  RNA_def_struct_register_funcs(srna, "rna_FunctionNode_register", "rna_Node_unregister", NULL);
+}
+
 /* -------------------------------------------------------------------------- */
 
 static void rna_def_node_socket(BlenderRNA *brna)
@@ -9830,6 +9971,7 @@ void RNA_def_nodetree(BlenderRNA *brna)
   rna_def_compositor_node(brna);
   rna_def_texture_node(brna);
   rna_def_simulation_node(brna);
+  rna_def_function_node(brna);
 
   rna_def_nodetree(brna);
 
index 84c82c84fd01c56b0bbecc5a6077dbbdc975ec62..469a230f4672345f36bd7ec1b8a7acd037908d3d 100644 (file)
@@ -21,6 +21,7 @@
 set(INC
   .
   composite
+  function
   intern
   shader
   simulation
@@ -128,6 +129,11 @@ set(SRC
   composite/node_composite_tree.c
   composite/node_composite_util.c
 
+  function/nodes/node_fn_boolean_math.cc
+  function/nodes/node_fn_float_compare.cc
+  function/nodes/node_fn_switch.cc
+  function/node_function_util.cc
+
   shader/nodes/node_shader_add_shader.c
   shader/nodes/node_shader_ambient_occlusion.c
   shader/nodes/node_shader_attribute.c
@@ -269,12 +275,14 @@ set(SRC
   intern/node_util.c
 
   composite/node_composite_util.h
+  function/node_function_util.h
   shader/node_shader_util.h
   simulation/node_simulation_util.h
   texture/node_texture_util.h
 
   NOD_common.h
   NOD_composite.h
+  NOD_function.h
   NOD_shader.h
   NOD_simulation.h
   NOD_socket.h
diff --git a/source/blender/nodes/NOD_function.h b/source/blender/nodes/NOD_function.h
new file mode 100644 (file)
index 0000000..58597b3
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __NOD_FUNCTION_H__
+#define __NOD_FUNCTION_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void register_node_type_fn_boolean_math(void);
+void register_node_type_fn_float_compare(void);
+void register_node_type_fn_switch(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __NOD_FUNCTION_H__ */
index bf484133afa71edd62fbd27023e1981c67ccce49..d228d92a55cc5a769a19f237210095dab1f71e6b 100644 (file)
@@ -271,7 +271,12 @@ DefNode(SimulationNode, SIM_NODE_EMIT_PARTICLES, 0,                      "EMIT_P
 DefNode(SimulationNode, SIM_NODE_TIME,           def_sim_time,           "TIME",                Time,               "Time",                 "")
 DefNode(SimulationNode, SIM_NODE_PARTICLE_ATTRIBUTE, def_sim_particle_attribute, "PARTICLE_ATTRIBUTE",  ParticleAttribute,  "Particle Attribute",   "")
 
+DefNode(FunctionNode, FN_NODE_BOOLEAN_MATH,  def_boolean_math,  "BOOLEAN_MATH",  BooleanMath,  "Boolean Math", "");
+DefNode(FunctionNode, FN_NODE_FLOAT_COMPARE, def_float_compare, "FLOAT_COMPARE", FloatCompare, "Float Compare", "");
+DefNode(FunctionNode, FN_NODE_SWITCH,        def_fn_switch,     "SWITCH",        Switch,       "Switch", "");
+
+
 /* undefine macros */
 #undef DefNode
 
-    /* clang-format on */
+/* clang-format on */
diff --git a/source/blender/nodes/function/node_function_util.cc b/source/blender/nodes/function/node_function_util.cc
new file mode 100644 (file)
index 0000000..0927ba3
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "node_function_util.h"
+#include "node_util.h"
+
+bool fn_node_poll_default(bNodeType *UNUSED(ntype), bNodeTree *ntree)
+{
+  /* Function nodes are only supported in simulation node trees so far. */
+  return STREQ(ntree->idname, "SimulationNodeTree");
+}
+
+void fn_node_type_base(bNodeType *ntype, int type, const char *name, short nclass, short flag)
+{
+  node_type_base(ntype, type, name, nclass, flag);
+  ntype->poll = fn_node_poll_default;
+}
diff --git a/source/blender/nodes/function/node_function_util.h b/source/blender/nodes/function/node_function_util.h
new file mode 100644 (file)
index 0000000..85e252f
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __NODE_FUNCTION_UTIL_H__
+#define __NODE_FUNCTION_UTIL_H__
+
+#include <string.h>
+
+#include "BLI_utildefines.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_node_types.h"
+
+#include "BKE_node.h"
+
+#include "BLT_translation.h"
+
+#include "NOD_function.h"
+
+#include "node_util.h"
+
+void fn_node_type_base(
+    struct bNodeType *ntype, int type, const char *name, short nclass, short flag);
+bool fn_node_poll_default(struct bNodeType *ntype, struct bNodeTree *ntree);
+
+#endif /* __NODE_FUNCTION_UTIL_H__ */
diff --git a/source/blender/nodes/function/nodes/node_fn_boolean_math.cc b/source/blender/nodes/function/nodes/node_fn_boolean_math.cc
new file mode 100644 (file)
index 0000000..615ad4c
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+
+#include "RNA_enum_types.h"
+
+#include "node_function_util.h"
+
+static bNodeSocketTemplate fn_node_boolean_math_in[] = {
+    {SOCK_BOOLEAN, N_("Boolean")},
+    {SOCK_BOOLEAN, N_("Boolean")},
+    {-1, ""},
+};
+
+static bNodeSocketTemplate fn_node_boolean_math_out[] = {
+    {SOCK_BOOLEAN, N_("Boolean")},
+    {-1, ""},
+};
+
+static void node_boolean_math_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+  bNodeSocket *sockB = (bNodeSocket *)BLI_findlink(&node->inputs, 1);
+
+  nodeSetSocketAvailability(sockB,
+                            ELEM(node->custom1, NODE_BOOLEAN_MATH_AND, NODE_BOOLEAN_MATH_OR));
+}
+
+static void node_boolean_math_label(bNodeTree *UNUSED(ntree), bNode *node, char *label, int maxlen)
+{
+  const char *name;
+  bool enum_label = RNA_enum_name(rna_enum_node_boolean_math_items, node->custom1, &name);
+  if (!enum_label) {
+    name = "Unknown";
+  }
+  BLI_strncpy(label, IFACE_(name), maxlen);
+}
+
+void register_node_type_fn_boolean_math()
+{
+  static bNodeType ntype;
+
+  fn_node_type_base(&ntype, FN_NODE_BOOLEAN_MATH, "Boolean Math", 0, 0);
+  node_type_socket_templates(&ntype, fn_node_boolean_math_in, fn_node_boolean_math_out);
+  node_type_label(&ntype, node_boolean_math_label);
+  node_type_update(&ntype, node_boolean_math_update);
+  nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/function/nodes/node_fn_float_compare.cc b/source/blender/nodes/function/nodes/node_fn_float_compare.cc
new file mode 100644 (file)
index 0000000..9788402
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+
+#include "RNA_enum_types.h"
+
+#include "node_function_util.h"
+
+static bNodeSocketTemplate fn_node_float_compare_in[] = {
+    {SOCK_FLOAT, N_("A"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
+    {SOCK_FLOAT, N_("B"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
+    {SOCK_FLOAT, N_("Epsilon"), 0.001f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
+    {-1, ""},
+};
+
+static bNodeSocketTemplate fn_node_float_compare_out[] = {
+    {SOCK_BOOLEAN, N_("Result")},
+    {-1, ""},
+};
+
+static void node_float_compare_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+  bNodeSocket *sockEpsilon = (bNodeSocket *)BLI_findlink(&node->inputs, 2);
+
+  nodeSetSocketAvailability(
+      sockEpsilon, ELEM(node->custom1, NODE_FLOAT_COMPARE_EQUAL, NODE_FLOAT_COMPARE_NOT_EQUAL));
+}
+
+static void node_float_compare_label(bNodeTree *UNUSED(ntree),
+                                     bNode *node,
+                                     char *label,
+                                     int maxlen)
+{
+  const char *name;
+  bool enum_label = RNA_enum_name(rna_enum_node_float_compare_items, node->custom1, &name);
+  if (!enum_label) {
+    name = "Unknown";
+  }
+  BLI_strncpy(label, IFACE_(name), maxlen);
+}
+
+void register_node_type_fn_float_compare()
+{
+  static bNodeType ntype;
+
+  fn_node_type_base(&ntype, FN_NODE_FLOAT_COMPARE, "Boolean Math", 0, 0);
+  node_type_socket_templates(&ntype, fn_node_float_compare_in, fn_node_float_compare_out);
+  node_type_label(&ntype, node_float_compare_label);
+  node_type_update(&ntype, node_float_compare_update);
+  nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/function/nodes/node_fn_switch.cc b/source/blender/nodes/function/nodes/node_fn_switch.cc
new file mode 100644 (file)
index 0000000..cb72105
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "BLI_listbase.h"
+#include "node_function_util.h"
+
+static bNodeSocketTemplate fn_node_switch_in[] = {
+    {SOCK_BOOLEAN, N_("Switch")},
+
+    {SOCK_FLOAT, N_("If False"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
+    {SOCK_INT, N_("If False"), 0, 0, 0, 0, -10000, 10000},
+    {SOCK_BOOLEAN, N_("If False")},
+    {SOCK_VECTOR, N_("If False"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
+    {SOCK_STRING, N_("If False")},
+    {SOCK_RGBA, N_("If False"), 0.8f, 0.8f, 0.8f, 1.0f},
+    {SOCK_OBJECT, N_("If False")},
+    {SOCK_IMAGE, N_("If False")},
+
+    {SOCK_FLOAT, N_("If True"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
+    {SOCK_INT, N_("If True"), 0, 0, 0, 0, -10000, 10000},
+    {SOCK_BOOLEAN, N_("If True")},
+    {SOCK_VECTOR, N_("If True"), 0.0f, 0.0f, 0.0f, 0.0f, -10000.0f, 10000.0f},
+    {SOCK_STRING, N_("If True")},
+    {SOCK_RGBA, N_("If True"), 0.8f, 0.8f, 0.8f, 1.0f},
+    {SOCK_OBJECT, N_("If True")},
+    {SOCK_IMAGE, N_("If True")},
+
+    {-1, ""},
+};
+
+static bNodeSocketTemplate fn_node_switch_out[] = {
+    {SOCK_FLOAT, N_("Result")},
+    {SOCK_INT, N_("Result")},
+    {SOCK_BOOLEAN, N_("Result")},
+    {SOCK_VECTOR, N_("Result")},
+    {SOCK_STRING, N_("Result")},
+    {SOCK_RGBA, N_("Result")},
+    {SOCK_OBJECT, N_("Result")},
+    {SOCK_IMAGE, N_("Result")},
+    {-1, ""},
+};
+
+static void fn_node_switch_update(bNodeTree *UNUSED(ntree), bNode *node)
+{
+  int index = 0;
+  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
+    nodeSetSocketAvailability(sock, index == 0 || sock->type == node->custom1);
+    index++;
+  }
+  LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
+    nodeSetSocketAvailability(sock, sock->type == node->custom1);
+  }
+}
+
+void register_node_type_fn_switch()
+{
+  static bNodeType ntype;
+
+  fn_node_type_base(&ntype, FN_NODE_SWITCH, "Switch", 0, 0);
+  node_type_socket_templates(&ntype, fn_node_switch_in, fn_node_switch_out);
+  node_type_update(&ntype, fn_node_switch_update);
+  nodeRegisterType(&ntype);
+}