[Bf-blender-cvs] [34cf33eb120] master: Geometry Nodes: Switch Node Fields Update

guitargeek noreply at git.blender.org
Sun Oct 3 00:35:06 CEST 2021


Commit: 34cf33eb12099d3a1940de070d7dc7e88e3bebc7
Author: guitargeek
Date:   Sat Oct 2 17:33:25 2021 -0500
Branches: master
https://developer.blender.org/rB34cf33eb12099d3a1940de070d7dc7e88e3bebc7

Geometry Nodes: Switch Node Fields Update

This update of the Switch node allows for field compatible types
to be switched through the node. This includes the following:

Float, Int, Bool, String, Vector, and Color

The remaining types are processed with the orginal code:

Geometry, Object, Collection, Texture, and Material

Because the old types require a diffent "switch" socket than the
field types, versioning for old files is included to move links
of those types to a new switch socket. Once fields of other types
are supported, this node can be updated to support them as well.

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

===================================================================

M	source/blender/blenkernel/BKE_blender_version.h
M	source/blender/blenloader/intern/versioning_300.c
M	source/blender/nodes/geometry/nodes/node_geo_switch.cc

===================================================================

diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index b04bbdfb187..31ce1b124e9 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -39,7 +39,7 @@ extern "C" {
 
 /* Blender file format version. */
 #define BLENDER_FILE_VERSION BLENDER_VERSION
-#define BLENDER_FILE_SUBVERSION 31
+#define BLENDER_FILE_SUBVERSION 32
 
 /* Minimum Blender version that supports reading file written with the current
  * version. Older Blender versions will test this and show a warning if the file
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index 11b6ad9b8ea..5b436d59213 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -617,6 +617,32 @@ void do_versions_after_linking_300(Main *bmain, ReportList *UNUSED(reports))
     do_versions_idproperty_ui_data(bmain);
   }
 
+  if (!MAIN_VERSION_ATLEAST(bmain, 300, 32)) {
+    /* Update Switch Node Non-Fields switch input to Switch_001. */
+    LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
+      if (ntree->type != NTREE_GEOMETRY) {
+        continue;
+      }
+
+      LISTBASE_FOREACH (bNodeLink *, link, &ntree->links) {
+        if (link->tonode->type == GEO_NODE_SWITCH) {
+          if (STREQ(link->tosock->identifier, "Switch")) {
+            bNode *to_node = link->tonode;
+
+            uint8_t mode = ((NodeSwitch *)to_node->storage)->input_type;
+            if (ELEM(mode,
+                     SOCK_GEOMETRY,
+                     SOCK_OBJECT,
+                     SOCK_COLLECTION,
+                     SOCK_TEXTURE,
+                     SOCK_MATERIAL)) {
+              link->tosock = link->tosock->next;
+            }
+          }
+        }
+      }
+    }
+  }
   /**
    * Versioning code until next subversion bump goes here.
    *
diff --git a/source/blender/nodes/geometry/nodes/node_geo_switch.cc b/source/blender/nodes/geometry/nodes/node_geo_switch.cc
index ca857c4d2e3..05df927fb39 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_switch.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_switch.cc
@@ -19,24 +19,37 @@
 #include "UI_interface.h"
 #include "UI_resources.h"
 
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+
+#include "BKE_material.h"
+
+#include "FN_multi_function_signature.hh"
+
 namespace blender::nodes {
 
 static void geo_node_switch_declare(NodeDeclarationBuilder &b)
 {
-  b.add_input<decl::Bool>("Switch");
-
-  b.add_input<decl::Float>("False");
-  b.add_input<decl::Float>("True");
-  b.add_input<decl::Int>("False", "False_001").min(-100000).max(100000);
-  b.add_input<decl::Int>("True", "True_001").min(-100000).max(100000);
-  b.add_input<decl::Bool>("False", "False_002");
-  b.add_input<decl::Bool>("True", "True_002");
-  b.add_input<decl::Vector>("False", "False_003");
-  b.add_input<decl::Vector>("True", "True_003");
-  b.add_input<decl::Color>("False", "False_004").default_value({0.8f, 0.8f, 0.8f, 1.0f});
-  b.add_input<decl::Color>("True", "True_004").default_value({0.8f, 0.8f, 0.8f, 1.0f});
-  b.add_input<decl::String>("False", "False_005");
-  b.add_input<decl::String>("True", "True_005");
+  b.add_input<decl::Bool>("Switch").default_value(false).supports_field();
+  b.add_input<decl::Bool>("Switch", "Switch_001").default_value(false);
+
+  b.add_input<decl::Float>("False").supports_field();
+  b.add_input<decl::Float>("True").supports_field();
+  b.add_input<decl::Int>("False", "False_001").min(-100000).max(100000).supports_field();
+  b.add_input<decl::Int>("True", "True_001").min(-100000).max(100000).supports_field();
+  b.add_input<decl::Bool>("False", "False_002").default_value(false).hide_value().supports_field();
+  b.add_input<decl::Bool>("True", "True_002").default_value(true).hide_value().supports_field();
+  b.add_input<decl::Vector>("False", "False_003").supports_field();
+  b.add_input<decl::Vector>("True", "True_003").supports_field();
+  b.add_input<decl::Color>("False", "False_004")
+      .default_value({0.8f, 0.8f, 0.8f, 1.0f})
+      .supports_field();
+  b.add_input<decl::Color>("True", "True_004")
+      .default_value({0.8f, 0.8f, 0.8f, 1.0f})
+      .supports_field();
+  b.add_input<decl::String>("False", "False_005").supports_field();
+  b.add_input<decl::String>("True", "True_005").supports_field();
+
   b.add_input<decl::Geometry>("False", "False_006");
   b.add_input<decl::Geometry>("True", "True_006");
   b.add_input<decl::Object>("False", "False_007");
@@ -48,12 +61,12 @@ static void geo_node_switch_declare(NodeDeclarationBuilder &b)
   b.add_input<decl::Material>("False", "False_010");
   b.add_input<decl::Material>("True", "True_010");
 
-  b.add_output<decl::Float>("Output");
-  b.add_output<decl::Int>("Output", "Output_001");
-  b.add_output<decl::Bool>("Output", "Output_002");
-  b.add_output<decl::Vector>("Output", "Output_003");
-  b.add_output<decl::Color>("Output", "Output_004");
-  b.add_output<decl::String>("Output", "Output_005");
+  b.add_output<decl::Float>("Output").dependent_field();
+  b.add_output<decl::Int>("Output", "Output_001").dependent_field();
+  b.add_output<decl::Bool>("Output", "Output_002").dependent_field();
+  b.add_output<decl::Vector>("Output", "Output_003").dependent_field();
+  b.add_output<decl::Color>("Output", "Output_004").dependent_field();
+  b.add_output<decl::String>("Output", "Output_005").dependent_field();
   b.add_output<decl::Geometry>("Output", "Output_006");
   b.add_output<decl::Object>("Output", "Output_007");
   b.add_output<decl::Collection>("Output", "Output_008");
@@ -77,91 +90,168 @@ static void geo_node_switch_update(bNodeTree *UNUSED(ntree), bNode *node)
 {
   NodeSwitch *node_storage = (NodeSwitch *)node->storage;
   int index = 0;
-  LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
-    nodeSetSocketAvailability(
-        socket, index == 0 || socket->type == (eNodeSocketDatatype)node_storage->input_type);
-    index++;
+  bNodeSocket *field_switch = (bNodeSocket *)node->inputs.first;
+  bNodeSocket *non_field_switch = (bNodeSocket *)field_switch->next;
+
+  const bool fields_type = ELEM((eNodeSocketDatatype)node_storage->input_type,
+                                SOCK_FLOAT,
+                                SOCK_INT,
+                                SOCK_BOOLEAN,
+                                SOCK_VECTOR,
+                                SOCK_RGBA,
+                                SOCK_STRING);
+
+  nodeSetSocketAvailability(field_switch, fields_type);
+  nodeSetSocketAvailability(non_field_switch, !fields_type);
+
+  LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, &node->inputs, index) {
+    if (index <= 1) {
+      continue;
+    }
+    nodeSetSocketAvailability(socket,
+                              socket->type == (eNodeSocketDatatype)node_storage->input_type);
   }
+
   LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
     nodeSetSocketAvailability(socket,
                               socket->type == (eNodeSocketDatatype)node_storage->input_type);
   }
 }
 
-template<typename T>
-static void output_input(GeoNodeExecParams &params,
-                         const bool input,
-                         const StringRef input_suffix,
-                         const StringRef output_identifier)
+template<typename T> class SwitchFieldsFunction : public fn::MultiFunction {
+ public:
+  SwitchFieldsFunction()
+  {
+    static fn::MFSignature signature = create_signature();
+    this->set_signature(&signature);
+  }
+  static fn::MFSignature create_signature()
+  {
+    fn::MFSignatureBuilder signature{"Switch"};
+    signature.single_input<bool>("Switch");
+    signature.single_input<T>("False");
+    signature.single_input<T>("True");
+    signature.single_output<T>("Output");
+    return signature.build();
+  }
+
+  void call(IndexMask mask, fn::MFParams params, fn::MFContext UNUSED(context)) const override
+  {
+    const VArray<bool> &switches = params.readonly_single_input<bool>(0, "Switch");
+    const VArray<T> &falses = params.readonly_single_input<T>(1, "False");
+    const VArray<T> &trues = params.readonly_single_input<T>(2, "True");
+    MutableSpan<T> values = params.uninitialized_single_output_if_required<T>(3, "Output");
+    for (int64_t i : mask) {
+      new (&values[i]) T(switches[i] ? trues[i] : falses[i]);
+    }
+  }
+};
+
+template<typename T> void switch_fields(GeoNodeExecParams &params, const StringRef suffix)
+{
+  if (params.lazy_require_input("Switch")) {
+    return;
+  }
+
+  const std::string name_false = "False" + suffix;
+  const std::string name_true = "True" + suffix;
+  const std::string name_output = "Output" + suffix;
+
+  /* TODO: Allow for Laziness when the switch field is constant. */
+  const bool require_false = params.lazy_require_input(name_false);
+  const bool require_true = params.lazy_require_input(name_true);
+  if (require_false | require_true) {
+    return;
+  }
+
+  Field<bool> switches_field = params.extract_input<Field<bool>>("Switch");
+  Field<T> falses_field = params.extract_input<Field<T>>(name_false);
+  Field<T> trues_field = params.extract_input<Field<T>>(name_true);
+
+  auto switch_fn = std::make_unique<SwitchFieldsFunction<T>>();
+  auto switch_op = std::make_shared<FieldOperation>(FieldOperation(
+      std::move(switch_fn),
+      {std::move(switches_field), std::move(falses_field), std::move(trues_field)}));
+
+  params.set_output(name_output, Field<T>(switch_op, 0));
+}
+
+template<typename T> void switch_no_fields(GeoNodeExecParams &params, const StringRef suffix)
 {
-  const std::string name_a = "False" + input_suffix;
-  const std::string name_b = "True" + input_suffix;
-  if (input) {
-    params.set_input_unused(name_a);
-    if (params.lazy_require_input(name_b)) {
+  if (params.lazy_require_input("Switch_001")) {
+    return;
+  }
+  bool switch_value = params.get_input<bool>("Switch_001");
+
+  const std::string name_false = "False" + suffix;
+  const std::string name_true = "True" + suffix;
+  const std::string name_output = "Output" + suffix;
+
+  if (switch_value) {
+    params.set_input_unused(

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list