[Bf-blender-cvs] [3aca0bc66a4] master: Geometry Nodes: simplify handling of invalid group interface sockets

Jacques Lucke noreply at git.blender.org
Fri Dec 16 18:34:37 CET 2022


Commit: 3aca0bc66a479e1cca9b688e8140da3ee06e8397
Author: Jacques Lucke
Date:   Fri Dec 16 18:30:47 2022 +0100
Branches: master
https://developer.blender.org/rB3aca0bc66a479e1cca9b688e8140da3ee06e8397

Geometry Nodes: simplify handling of invalid group interface sockets

Previously, the code tried to keep node groups working even if some of
their input/output sockets had undefined type. This caused some
complexity with no benefit because not all places outside of this file
would handle the case correctly. Now node groups with undefined
interface sockets are disabled and have to be fixed manually before
they work again.

Undefined interface sockets are mostly caused by invalid Python
API usage and incomplete forward compatibility (e.g. when newer
versions introduce new socket types that the older version does
not know).

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

M	source/blender/blenkernel/BKE_node_runtime.hh
M	source/blender/blenkernel/intern/node_runtime.cc
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/nodes/intern/geometry_nodes_lazy_function.cc

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

diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh
index 6a00e70cb5b..b4b9df32663 100644
--- a/source/blender/blenkernel/BKE_node_runtime.hh
+++ b/source/blender/blenkernel/BKE_node_runtime.hh
@@ -141,6 +141,8 @@ class bNodeTreeRuntime : NonCopyable, NonMovable {
   bool has_undefined_nodes_or_sockets = false;
   bNode *group_output_node = nullptr;
   Vector<bNode *> root_frames;
+  Vector<bNodeSocket *> interface_inputs;
+  Vector<bNodeSocket *> interface_outputs;
 };
 
 /**
@@ -426,6 +428,18 @@ inline blender::Span<const bNode *> bNodeTree::group_input_nodes() const
   return this->nodes_by_type("NodeGroupInput");
 }
 
+inline blender::Span<const bNodeSocket *> bNodeTree::interface_inputs() const
+{
+  BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this));
+  return this->runtime->interface_inputs;
+}
+
+inline blender::Span<const bNodeSocket *> bNodeTree::interface_outputs() const
+{
+  BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this));
+  return this->runtime->interface_outputs;
+}
+
 inline blender::Span<const bNodeSocket *> bNodeTree::all_input_sockets() const
 {
   BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this));
diff --git a/source/blender/blenkernel/intern/node_runtime.cc b/source/blender/blenkernel/intern/node_runtime.cc
index 4bdc8f6f9b8..0f0b04f920e 100644
--- a/source/blender/blenkernel/intern/node_runtime.cc
+++ b/source/blender/blenkernel/intern/node_runtime.cc
@@ -42,6 +42,13 @@ static void double_checked_lock_with_task_isolation(std::mutex &mutex,
   double_checked_lock(mutex, data_is_dirty, [&]() { threading::isolate_task(fn); });
 }
 
+static void update_interface_sockets(const bNodeTree &ntree)
+{
+  bNodeTreeRuntime &tree_runtime = *ntree.runtime;
+  tree_runtime.interface_inputs = ntree.inputs;
+  tree_runtime.interface_outputs = ntree.outputs;
+}
+
 static void update_node_vector(const bNodeTree &ntree)
 {
   bNodeTreeRuntime &tree_runtime = *ntree.runtime;
@@ -429,6 +436,7 @@ static void ensure_topology_cache(const bNodeTree &ntree)
   bNodeTreeRuntime &tree_runtime = *ntree.runtime;
   double_checked_lock_with_task_isolation(
       tree_runtime.topology_cache_mutex, tree_runtime.topology_cache_is_dirty, [&]() {
+        update_interface_sockets(ntree);
         update_node_vector(ntree);
         update_link_vector(ntree);
         update_socket_vectors_and_owner_node(ntree);
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index eddc26fe867..6acb2208962 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -636,6 +636,9 @@ typedef struct bNodeTree {
   const bNode *group_output_node() const;
   /** Get all input nodes of the node group. */
   blender::Span<const bNode *> group_input_nodes() const;
+  /** Inputs and outputs of the entire node group. */
+  blender::Span<const bNodeSocket *> interface_inputs() const;
+  blender::Span<const bNodeSocket *> interface_outputs() const;
 #endif
 } bNodeTree;
 
diff --git a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc
index 8d11089f253..9ded1827ccc 100644
--- a/source/blender/nodes/intern/geometry_nodes_lazy_function.cc
+++ b/source/blender/nodes/intern/geometry_nodes_lazy_function.cc
@@ -746,20 +746,9 @@ struct GeometryNodesLazyFunctionGraphBuilder {
 
   /**
    * All group input nodes are combined into one dummy node in the lazy-function graph.
-   * If some input has an invalid type, it is ignored in the new graph. In this case null and -1 is
-   * used in the vectors below.
    */
-  Vector<const CPPType *> group_input_types_;
-  Vector<int> group_input_indices_;
   lf::DummyNode *group_input_lf_node_;
 
-  /**
-   * The output types or null if an output is invalid. Each group output node gets a separate
-   * corresponding dummy node in the new graph.
-   */
-  Vector<const CPPType *> group_output_types_;
-  Vector<int> group_output_indices_;
-
  public:
   GeometryNodesLazyFunctionGraphBuilder(const bNodeTree &btree,
                                         GeometryNodesLazyFunctionGraphInfo &lf_graph_info)
@@ -776,8 +765,6 @@ struct GeometryNodesLazyFunctionGraphBuilder {
     conversions_ = &bke::get_implicit_type_conversions();
 
     this->prepare_node_multi_functions();
-    this->prepare_group_inputs();
-    this->prepare_group_outputs();
     this->build_group_input_node();
     this->handle_nodes();
     this->handle_links();
@@ -793,50 +780,21 @@ struct GeometryNodesLazyFunctionGraphBuilder {
     lf_graph_info_->node_multi_functions = std::make_unique<NodeMultiFunctions>(btree_);
   }
 
-  void prepare_group_inputs()
-  {
-    LISTBASE_FOREACH (const bNodeSocket *, interface_bsocket, &btree_.inputs) {
-      const CPPType *type = get_socket_cpp_type(*interface_bsocket->typeinfo);
-      if (type != nullptr) {
-        const int index = group_input_types_.append_and_get_index(type);
-        group_input_indices_.append(index);
-      }
-      else {
-        group_input_indices_.append(-1);
-      }
-    }
-  }
-
-  void prepare_group_outputs()
+  void build_group_input_node()
   {
-    LISTBASE_FOREACH (const bNodeSocket *, interface_bsocket, &btree_.outputs) {
-      const CPPType *type = get_socket_cpp_type(*interface_bsocket->typeinfo);
-      if (type != nullptr) {
-        const int index = group_output_types_.append_and_get_index(type);
-        group_output_indices_.append(index);
-      }
-      else {
-        group_output_indices_.append(-1);
-      }
+    Vector<const CPPType *, 16> input_cpp_types;
+    const Span<const bNodeSocket *> interface_inputs = btree_.interface_inputs();
+    for (const bNodeSocket *interface_input : interface_inputs) {
+      input_cpp_types.append(interface_input->typeinfo->geometry_nodes_cpp_type);
     }
-  }
 
-  void build_group_input_node()
-  {
     /* Create a dummy node for the group inputs. */
     auto debug_info = std::make_unique<GroupInputDebugInfo>();
-    group_input_lf_node_ = &lf_graph_->add_dummy({}, group_input_types_, debug_info.get());
+    group_input_lf_node_ = &lf_graph_->add_dummy({}, input_cpp_types, debug_info.get());
 
-    const bNodeSocket *interface_bsocket = static_cast<bNodeSocket *>(btree_.inputs.first);
-    for (const int group_input_index : group_input_indices_) {
-      BLI_SCOPED_DEFER([&]() { interface_bsocket = interface_bsocket->next; });
-      if (group_input_index == -1) {
-        mapping_->group_input_sockets.append(nullptr);
-      }
-      else {
-        mapping_->group_input_sockets.append(&group_input_lf_node_->output(group_input_index));
-        debug_info->socket_names.append(interface_bsocket->name);
-      }
+    for (const int i : interface_inputs.index_range()) {
+      mapping_->group_input_sockets.append(&group_input_lf_node_->output(i));
+      debug_info->socket_names.append(interface_inputs[i]->name);
     }
     lf_graph_info_->dummy_debug_infos_.append(std::move(debug_info));
   }
@@ -946,13 +904,9 @@ struct GeometryNodesLazyFunctionGraphBuilder {
 
   void handle_group_input_node(const bNode &bnode)
   {
-    for (const int btree_index : group_input_indices_.index_range()) {
-      const int lf_index = group_input_indices_[btree_index];
-      if (lf_index == -1) {
-        continue;
-      }
-      const bNodeSocket &bsocket = bnode.output_socket(btree_index);
-      lf::OutputSocket &lf_socket = group_input_lf_node_->output(lf_index);
+    for (const int i : btree_.interface_inputs().index_range()) {
+      const bNodeSocket &bsocket = bnode.output_socket(i);
+      lf::OutputSocket &lf_socket = group_input_lf_node_->output(i);
       output_socket_map_.add_new(&bsocket, &lf_socket);
       mapping_->dummy_socket_map.add_new(&bsocket, &lf_socket);
       mapping_->bsockets_by_lf_socket_map.add(&lf_socket, &bsocket);
@@ -961,23 +915,23 @@ struct GeometryNodesLazyFunctionGraphBuilder {
 
   void handle_group_output_node(const bNode &bnode)
   {
+    Vector<const CPPType *, 16> output_cpp_types;
+    const Span<const bNodeSocket *> interface_outputs = btree_.interface_outputs();
+    for (const bNodeSocket *interface_input : interface_outputs) {
+      output_cpp_types.append(interface_input->typeinfo->geometry_nodes_cpp_type);
+    }
+
     auto debug_info = std::make_unique<GroupOutputDebugInfo>();
     lf::DummyNode &group_output_lf_node = lf_graph_->add_dummy(
-        group_output_types_, {}, debug_info.get());
+        output_cpp_types, {}, debug_info.get());
 
-    const bNodeSocket *interface_bsocket = static_cast<bNodeSocket *>(btree_.outputs.first);
-    for (const int btree_index : group_output_indices_.index_range()) {
-      BLI_SCOPED_DEFER([&]() { interface_bsocket = interface_bsocket->next; });
-      const int lf_index = group_output_indices_[btree_index];
-      if (lf_index == -1) {
-        continue;
-      }
-      const bNodeSocket &bsocket = bnode.input_socket(btree_index);
-      lf::InputSocket &lf_socket = group_output_lf_node.input(lf_index);
+    for (const int i : interface_outputs.index_range()) {
+      const bNodeSocket &bsocket = bnode.input_socket(i);
+      lf::InputSocket &lf_socket = group_output_lf_node.input(i);
       input_socket_map_.add(&bsocket, &lf_socket);
       mapping_->dummy_socket_map.add(&bsocket, &lf_socket);
       mapping_->bsockets_by_lf_socket_map.add(&lf_socket, &bsocket);
-      debug_info->socket_names.append(interface_bsocket->name);
+      debug_info->socket_names.append(interface_outputs[i]->name);
     }
 
     lf_graph_info_->dummy_debug_infos_.append(std::move(debug_info));
@@ -1310,6 +1264,16 @@ const GeometryNodesLazyFunctionGraphInfo *ensure_geometry_nodes_lazy_function_gr
       return nullptr;
     }
   }
+  for (const bNodeSocket *interface_bsocket : btree.interface_inputs()) {
+    if (interface_bsocket->typeinfo->geometry_nodes_cpp_type == nullptr) {
+      return nullptr;
+    }
+  }
+  for (const bNodeSocket *interface_bsocket : btree.interface_outputs()) {
+    if (interface_bsocket->typeinfo->geometry_nodes_cpp_type == nullptr) {
+      return nullptr;
+    }
+  }
 
 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list