[Bf-blender-cvs] [23ef20855b9] temp-enum-socket: progress

Jacques Lucke noreply at git.blender.org
Mon Nov 8 16:07:03 CET 2021


Commit: 23ef20855b9d46915e53e29481fc72d83e4bee2d
Author: Jacques Lucke
Date:   Sun Nov 7 13:42:25 2021 +0100
Branches: temp-enum-socket
https://developer.blender.org/rB23ef20855b9d46915e53e29481fc72d83e4bee2d

progress

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

M	source/blender/blenkernel/intern/node.cc
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/NOD_geometry_exec.hh
M	source/blender/nodes/NOD_socket_declarations.hh
M	source/blender/nodes/geometry/nodes/node_geo_switch.cc
M	source/blender/nodes/intern/node_socket.cc
M	source/blender/nodes/intern/node_socket_declarations.cc

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

diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index 258b3080c54..98f5622ba77 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -5080,22 +5080,73 @@ namespace blender::bke::enum_inferencing {
 
 static bool update_enum_inferencing(const NodeTreeRef &tree)
 {
+  using namespace blender::nodes;
+
   bNodeTree &btree = *tree.btree();
 
-  for (const NodeRef *node : tree.nodes()) {
+  const NodeTreeRef::ToposortResult toposort_result = tree.toposort(
+      NodeTreeRef::ToposortDirection::RightToLeft);
+
+  Map<const SocketRef *, const std::shared_ptr<decl::EnumItems> *> enum_by_socket;
+
+  for (const NodeRef *node : toposort_result.sorted_nodes) {
     bNode &bnode = *node->bnode();
     nodeDeclarationEnsure(&btree, &bnode);
     const NodeDeclaration *node_decl = bnode.declaration;
-    for (const int i : node->inputs().index_range()) {
-      const InputSocketRef &socket = node->input(i);
-      if (socket.typeinfo()->type == SOCK_ENUM) {
-        bNodeSocketValueEnum *socket_value =
-            (bNodeSocketValueEnum *)socket.bsocket()->default_value;
-        const nodes::decl::Enum &enum_decl = static_cast<const nodes::decl::Enum &>(
-            *node_decl->inputs()[i]);
-        socket_value->items = enum_decl.items()->items();
+
+    for (const OutputSocketRef *socket : node->outputs()) {
+      if (socket->typeinfo()->type != SOCK_ENUM) {
+        continue;
+      }
+      /* TODO: Handle case when connected to incompatible enums. */
+      for (const InputSocketRef *target_socket : socket->directly_linked_sockets()) {
+        const std::shared_ptr<decl::EnumItems> *socket_items = enum_by_socket.lookup_default(
+            target_socket, nullptr);
+        enum_by_socket.add_new(socket, socket_items);
+        break;
       }
     }
+
+    for (const InputSocketRef *socket : node->inputs()) {
+      const int index = socket->index();
+      if (socket->typeinfo()->type != SOCK_ENUM) {
+        continue;
+      }
+      const nodes::decl::Enum &enum_decl = static_cast<const nodes::decl::Enum &>(
+          *node_decl->inputs()[index]);
+      const std::shared_ptr<decl::EnumItems> &items = enum_decl.items();
+      const std::shared_ptr<decl::EnumItems> *socket_items = nullptr;
+      if (items) {
+        socket_items = &items;
+      }
+      else {
+        int inference_index = enum_decl.inference_index();
+        if (inference_index == -1) {
+          for (const OutputSocketRef *output_socket : node->outputs()) {
+            if (output_socket->typeinfo()->type == SOCK_ENUM) {
+              inference_index = output_socket->index();
+              break;
+            }
+          }
+        }
+        BLI_assert(inference_index >= 0);
+        const OutputSocketRef &output_socket = node->output(inference_index);
+        socket_items = enum_by_socket.lookup_default(&output_socket, nullptr);
+      }
+      enum_by_socket.add_new(socket, socket_items);
+    }
+  }
+
+  for (const auto item : enum_by_socket.items()) {
+    const SocketRef *socket = item.key;
+    const std::shared_ptr<decl::EnumItems> *socket_items = item.value;
+    bNodeSocketValueEnum *socket_value = (bNodeSocketValueEnum *)socket->bsocket()->default_value;
+    if (socket_items != nullptr) {
+      socket_value->items = socket_items->get()->items();
+    }
+    else {
+      socket_value->items = nullptr;
+    }
   }
 
   return false;
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 9a5976b1182..9ea945e91bf 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -2059,7 +2059,8 @@ static bool switch_type_supported(const EnumPropertyItem *item)
               SOCK_COLLECTION,
               SOCK_TEXTURE,
               SOCK_MATERIAL,
-              SOCK_IMAGE);
+              SOCK_IMAGE,
+              SOCK_ENUM);
 }
 
 static const EnumPropertyItem *rna_GeometryNodeSwitch_type_itemf(bContext *UNUSED(C),
diff --git a/source/blender/nodes/NOD_geometry_exec.hh b/source/blender/nodes/NOD_geometry_exec.hh
index 6e1f21dbae0..331cb9b1dd5 100644
--- a/source/blender/nodes/NOD_geometry_exec.hh
+++ b/source/blender/nodes/NOD_geometry_exec.hh
@@ -356,4 +356,9 @@ class GeoNodeExecParams {
   const bNodeSocket *find_available_socket(const StringRef name) const;
 };
 
+/** Wrapper for an integer so that one can not perform various operations like addition on it. */
+struct EnumValue {
+  int value;
+};
+
 }  // namespace blender::nodes
diff --git a/source/blender/nodes/NOD_socket_declarations.hh b/source/blender/nodes/NOD_socket_declarations.hh
index d95ece947aa..b2ce7521137 100644
--- a/source/blender/nodes/NOD_socket_declarations.hh
+++ b/source/blender/nodes/NOD_socket_declarations.hh
@@ -185,6 +185,7 @@ class Enum : public SocketDeclaration {
  private:
   int default_value_ = 0;
   std::shared_ptr<EnumItems> items_;
+  int inference_index_ = -1;
 
   friend EnumBuilder;
 
@@ -192,6 +193,7 @@ class Enum : public SocketDeclaration {
   using Builder = EnumBuilder;
 
   const std::shared_ptr<EnumItems> &items() const;
+  int inference_index() const;
 
   bNodeSocket &build(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_out) const override;
   bool matches(const bNodeSocket &socket) const override;
@@ -203,6 +205,7 @@ class EnumBuilder : public SocketDeclarationBuilder<Enum> {
 
   EnumBuilder &static_items(const EnumPropertyItem *items);
   EnumBuilder &dynamic_items(std::shared_ptr<EnumItems> items);
+  EnumBuilder &inference_items(const int output_index = -1);
 };
 
 class IDSocketDeclaration : public SocketDeclaration {
diff --git a/source/blender/nodes/geometry/nodes/node_geo_switch.cc b/source/blender/nodes/geometry/nodes/node_geo_switch.cc
index 7e07a552650..ee556e01acf 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_switch.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_switch.cc
@@ -68,6 +68,8 @@ static void geo_node_switch_declare(NodeDeclarationBuilder &b)
   b.add_input<decl::Material>(N_("True"), "True_010");
   b.add_input<decl::Image>(N_("False"), "False_011");
   b.add_input<decl::Image>(N_("True"), "True_011");
+  b.add_input<decl::Enum>(N_("False"), "False_012");
+  b.add_input<decl::Enum>(N_("True"), "True_012");
 
   b.add_output<decl::Float>(N_("Output")).dependent_field();
   b.add_output<decl::Int>(N_("Output"), "Output_001").dependent_field();
@@ -81,6 +83,7 @@ static void geo_node_switch_declare(NodeDeclarationBuilder &b)
   b.add_output<decl::Texture>(N_("Output"), "Output_009");
   b.add_output<decl::Material>(N_("Output"), "Output_010");
   b.add_output<decl::Image>(N_("Output"), "Output_011");
+  b.add_output<decl::Enum>(N_("Output"), "Output_012").inference_items();
 }
 
 static void geo_node_switch_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
@@ -287,6 +290,10 @@ static void geo_node_switch_exec(GeoNodeExecParams params)
       switch_no_fields<Image *>(params, "_011");
       break;
     }
+    case SOCK_ENUM: {
+      switch_no_fields<EnumValue>(params, "_012");
+      break;
+    }
     default:
       BLI_assert_unreachable();
       break;
diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc
index 585b5969b1e..69367953618 100644
--- a/source/blender/nodes/intern/node_socket.cc
+++ b/source/blender/nodes/intern/node_socket.cc
@@ -44,6 +44,7 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "NOD_geometry_exec.hh"
 #include "NOD_node_declaration.hh"
 #include "NOD_socket.h"
 
@@ -824,6 +825,7 @@ MAKE_CPP_TYPE(Collection, Collection *, CPPTypeFlags::BasicType)
 MAKE_CPP_TYPE(Texture, Tex *, CPPTypeFlags::BasicType)
 MAKE_CPP_TYPE(Image, Image *, CPPTypeFlags::BasicType)
 MAKE_CPP_TYPE(Material, Material *, CPPTypeFlags::BasicType)
+MAKE_CPP_TYPE(EnumValue, blender::nodes::EnumValue, CPPTypeFlags::None)
 
 static bNodeSocketType *make_socket_type_object()
 {
@@ -900,6 +902,15 @@ static bNodeSocketType *make_socket_type_material()
 static bNodeSocketType *make_socket_type_enum()
 {
   bNodeSocketType *socktype = make_standard_socket_type(SOCK_ENUM, PROP_NONE);
+  socktype->get_base_cpp_type = []() {
+    return &blender::fn::CPPType::get<blender::nodes::EnumValue>();
+  };
+  socktype->get_base_cpp_value = [](const bNodeSocket &socket, void *r_value) {
+    ((blender::nodes::EnumValue *)r_value)->value =
+        ((bNodeSocketValueEnum *)socket.default_value)->value;
+  };
+  socktype->get_geometry_nodes_cpp_type = socktype->get_base_cpp_type;
+  socktype->get_geometry_nodes_cpp_value = socktype->get_base_cpp_value;
   return socktype;
 }
 
diff --git a/source/blender/nodes/intern/node_socket_declarations.cc b/source/blender/nodes/intern/node_socket_declarations.cc
index 9a4bd58a280..5204acda265 100644
--- a/source/blender/nodes/intern/node_socket_declarations.cc
+++ b/source/blender/nodes/intern/node_socket_declarations.cc
@@ -306,6 +306,11 @@ const std::shared_ptr<EnumItems> &Enum::items() const
   return items_;
 }
 
+int Enum::inference_index() const
+{
+  return inference_index_;
+}
+
 bNodeSocket &Enum::build(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_out) const
 {
   bNodeSocket &socket = *nodeAddStaticSocket(
@@ -339,6 +344,12 @@ EnumBuilder &EnumBuilder::dynamic_items(std::shared_ptr<EnumItems> items)
   return *this;
 }
 
+EnumBuilder &EnumBuilder::inference_items(const int output_index)
+{
+  decl_->inference_index_ = output_index;
+  return *this;
+}
+
 /** \} */
 
 /* -------------------------------------------------------------------- */



More information about the Bf-blender-cvs mailing list