[Bf-blender-cvs] [797064544ea] master: Geometry Nodes: Only show attribute toggle for field inputs

Hans Goudey noreply at git.blender.org
Tue Sep 28 19:05:52 CEST 2021


Commit: 797064544ea3e176c511f7ff7c1303498a783182
Author: Hans Goudey
Date:   Tue Sep 28 12:05:42 2021 -0500
Branches: master
https://developer.blender.org/rB797064544ea3e176c511f7ff7c1303498a783182

Geometry Nodes: Only show attribute toggle for field inputs

Change the toggle to switch between an attribute and a single value to
only display for inputs that are fields, as determined statically by
the field inferencing added in rB61f3d4eb7c7db7. This means the field
inferencing must be calculated on file load, since it's used in the UI.

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

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

M	source/blender/blenkernel/intern/node.cc
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/modifiers/intern/MOD_nodes.cc
M	source/blender/nodes/NOD_node_declaration.hh

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

diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index f2843e5f88e..c8ba7991f31 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -104,6 +104,7 @@ using blender::Span;
 using blender::Stack;
 using blender::Vector;
 using blender::VectorSet;
+using blender::nodes::FieldInferencingInterface;
 using blender::nodes::InputSocketFieldType;
 using blender::nodes::NodeDeclaration;
 using blender::nodes::OutputFieldDependency;
@@ -823,6 +824,11 @@ void ntreeBlendReadData(BlendDataReader *reader, bNodeTree *ntree)
   /* TODO: should be dealt by new generic cache handling of IDs... */
   ntree->previews = nullptr;
 
+  if (ntree->type == NTREE_GEOMETRY) {
+    /* Update field referencing for the geometry nodes modifier. */
+    ntree->update |= NTREE_UPDATE_FIELD_INFERENCING;
+  }
+
   /* type verification is in lib-link */
 }
 
@@ -4456,24 +4462,6 @@ void ntreeUpdateAllNew(Main *main)
   FOREACH_NODETREE_END;
 }
 
-/**
- * Information about how a node interacts with fields.
- */
-struct FieldInferencingInterface {
-  Vector<InputSocketFieldType> inputs;
-  Vector<OutputFieldDependency> outputs;
-
-  friend bool operator==(const FieldInferencingInterface &a, const FieldInferencingInterface &b)
-  {
-    return a.inputs == b.inputs && a.outputs == b.outputs;
-  }
-
-  friend bool operator!=(const FieldInferencingInterface &a, const FieldInferencingInterface &b)
-  {
-    return !(a == b);
-  }
-};
-
 static FieldInferencingInterface *node_field_inferencing_interface_copy(
     const FieldInferencingInterface &field_inferencing_interface)
 {
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 34c74e5bd88..f7f2ccaa7be 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -463,7 +463,15 @@ typedef struct bNodeLink {
 #define NTREE_CHUNKSIZE_512 512
 #define NTREE_CHUNKSIZE_1024 1024
 
+/** Workaround to forward-declare C++ type in C header. */
+#ifdef __cplusplus
+namespace blender::nodes {
 struct FieldInferencingInterface;
+}
+using FieldInferencingInterfaceHandle = blender::nodes::FieldInferencingInterface;
+#else
+typedef struct FieldInferencingInterfaceHandle FieldInferencingInterfaceHandle;
+#endif
 
 /* the basis for a Node tree, all links and nodes reside internal here */
 /* only re-usable node trees are in the library though,
@@ -488,7 +496,7 @@ typedef struct bNodeTree {
 
   ListBase nodes, links;
   /** Information about how inputs and outputs of the node group interact with fields. */
-  struct FieldInferencingInterface *field_inferencing_interface;
+  FieldInferencingInterfaceHandle *field_inferencing_interface;
 
   /** Set init on fileread. */
   int type, init;
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index d5dcf88b914..f2f9b82480d 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -88,6 +88,7 @@
 #include "NOD_derived_node_tree.hh"
 #include "NOD_geometry.h"
 #include "NOD_geometry_nodes_eval_log.hh"
+#include "NOD_node_declaration.hh"
 
 #include "FN_field.hh"
 #include "FN_multi_function.hh"
@@ -107,7 +108,9 @@ using blender::bke::OutputAttribute;
 using blender::fn::GField;
 using blender::fn::GMutablePointer;
 using blender::fn::GPointer;
+using blender::nodes::FieldInferencingInterface;
 using blender::nodes::GeoNodeExecParams;
+using blender::nodes::InputSocketFieldType;
 using blender::threading::EnumerableThreadSpecific;
 using namespace blender::fn::multi_function_types;
 using namespace blender::nodes::derived_node_tree_types;
@@ -308,6 +311,17 @@ static bool socket_type_has_attribute_toggle(const bNodeSocket &socket)
   return ELEM(socket.type, SOCK_FLOAT, SOCK_VECTOR, SOCK_BOOLEAN, SOCK_RGBA, SOCK_INT);
 }
 
+/**
+ * \return Whether using an attribute to input values of this type is supported, and the node
+ * group's input for this socket accepts a field rather than just single values.
+ */
+static bool input_has_attribute_toggle(const bNodeTree &node_tree, const int socket_index)
+{
+  BLI_assert(node_tree.field_inferencing_interface != nullptr);
+  const FieldInferencingInterface &field_interface = *node_tree.field_inferencing_interface;
+  return field_interface.inputs[socket_index] != InputSocketFieldType::None;
+}
+
 static IDProperty *id_property_create_from_socket(const bNodeSocket &socket)
 {
   switch (socket.type) {
@@ -533,7 +547,8 @@ void MOD_nodes_update_interface(Object *object, NodesModifierData *nmd)
     nmd->settings.properties = IDP_New(IDP_GROUP, &idprop, "Nodes Modifier Settings");
   }
 
-  LISTBASE_FOREACH (bNodeSocket *, socket, &nmd->node_group->inputs) {
+  int socket_index;
+  LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, &nmd->node_group->inputs, socket_index) {
     IDProperty *new_prop = id_property_create_from_socket(*socket);
     if (new_prop == nullptr) {
       /* Out of the set of supported input sockets, only
@@ -564,7 +579,7 @@ void MOD_nodes_update_interface(Object *object, NodesModifierData *nmd)
       }
     }
 
-    if (socket_type_has_attribute_toggle(*socket)) {
+    if (input_has_attribute_toggle(*nmd->node_group, socket_index)) {
       const std::string use_attribute_id = socket->identifier + use_attribute_suffix;
       const std::string attribute_name_id = socket->identifier + attribute_name_suffix;
 
@@ -655,37 +670,39 @@ void MOD_nodes_init(Main *bmain, NodesModifierData *nmd)
 }
 
 static void initialize_group_input(NodesModifierData &nmd,
-                                   const bNodeSocket &socket,
+                                   const OutputSocketRef &socket,
                                    void *r_value)
 {
+  const bNodeSocketType &socket_type = *socket.typeinfo();
+  const bNodeSocket &bsocket = *socket.bsocket();
   if (nmd.settings.properties == nullptr) {
-    socket.typeinfo->get_geometry_nodes_cpp_value(socket, r_value);
+    socket_type.get_geometry_nodes_cpp_value(bsocket, r_value);
     return;
   }
   const IDProperty *property = IDP_GetPropertyFromGroup(nmd.settings.properties,
-                                                        socket.identifier);
+                                                        socket.identifier().c_str());
   if (property == nullptr) {
-    socket.typeinfo->get_geometry_nodes_cpp_value(socket, r_value);
+    socket_type.get_geometry_nodes_cpp_value(bsocket, r_value);
     return;
   }
-  if (!id_property_type_matches_socket(socket, *property)) {
-    socket.typeinfo->get_geometry_nodes_cpp_value(socket, r_value);
+  if (!id_property_type_matches_socket(bsocket, *property)) {
+    socket_type.get_geometry_nodes_cpp_value(bsocket, r_value);
     return;
   }
 
-  if (!socket_type_has_attribute_toggle(socket)) {
+  if (!input_has_attribute_toggle(*nmd.node_group, socket.index())) {
     init_socket_cpp_value_from_property(
-        *property, static_cast<eNodeSocketDatatype>(socket.type), r_value);
+        *property, static_cast<eNodeSocketDatatype>(bsocket.type), r_value);
     return;
   }
 
   const IDProperty *property_use_attribute = IDP_GetPropertyFromGroup(
-      nmd.settings.properties, (socket.identifier + use_attribute_suffix).c_str());
+      nmd.settings.properties, (socket.identifier() + use_attribute_suffix).c_str());
   const IDProperty *property_attribute_name = IDP_GetPropertyFromGroup(
-      nmd.settings.properties, (socket.identifier + attribute_name_suffix).c_str());
+      nmd.settings.properties, (socket.identifier() + attribute_name_suffix).c_str());
   if (property_use_attribute == nullptr || property_attribute_name == nullptr) {
     init_socket_cpp_value_from_property(
-        *property, static_cast<eNodeSocketDatatype>(socket.type), r_value);
+        *property, static_cast<eNodeSocketDatatype>(bsocket.type), r_value);
     return;
   }
 
@@ -693,12 +710,12 @@ static void initialize_group_input(NodesModifierData &nmd,
   if (use_attribute) {
     const StringRef attribute_name{IDP_String(property_attribute_name)};
     auto attribute_input = std::make_shared<blender::bke::AttributeFieldInput>(
-        attribute_name, *socket.typeinfo->get_base_cpp_type());
+        attribute_name, *socket_type.get_base_cpp_type());
     new (r_value) blender::fn::GField(std::move(attribute_input), 0);
   }
   else {
     init_socket_cpp_value_from_property(
-        *property, static_cast<eNodeSocketDatatype>(socket.type), r_value);
+        *property, static_cast<eNodeSocketDatatype>(bsocket.type), r_value);
   }
 }
 
@@ -914,7 +931,7 @@ static GeometrySet compute_geometry(const DerivedNodeTree &tree,
     for (const OutputSocketRef *socket : remaining_input_sockets) {
       const CPPType &cpp_type = *socket->typeinfo()->get_geometry_nodes_cpp_type();
       void *value_in = allocator.allocate(cpp_type.size(), cpp_type.alignment());
-      initialize_group_input(*nmd, *socket->bsocket(), value_in);
+      initialize_group_input(*nmd, *socket, value_in);
       group_inputs.add_new({root_context, socket}, {cpp_type, value_in});
     }
   }
@@ -1079,11 +1096,12 @@ static void modifyGeometrySet(ModifierData *md,
 /* Drawing the properties manually with #uiItemR instead of #uiDefAutoButsRNA allows using
  * the node socket identifier for the property names, since they are unique, but also having
  * the correct label displayed in the UI. */
-static void draw_property_for_input_socket(uiLayout *layout,
-                                           NodesModifierData *nmd,
-                                           PointerRNA *bmain_ptr,
-                                           PointerRNA *md_ptr,
-                                           const bNodeSocket &socket)
+static void draw_property_for_socket(uiLayout *layout,
+                                     NodesModifierData *nmd,
+                                     PointerRNA *bmain_ptr,
+                                     PointerRNA *md_ptr,
+                                     const bNodeSocket &socket,
+                                     const int socket_index)
 {
   /* The property should be created in #MOD_nodes_update_in

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list