[Bf-blender-cvs] [8ed74c9dafb] geometry-nodes: Geometry Nodes: Use UI settings for properties in modifier

Hans Goudey noreply at git.blender.org
Thu Oct 29 20:11:38 CET 2020


Commit: 8ed74c9dafb9434669fadcd631d1183cce5c0d04
Author: Hans Goudey
Date:   Thu Oct 29 14:11:32 2020 -0500
Branches: geometry-nodes
https://developer.blender.org/rB8ed74c9dafb9434669fadcd631d1183cce5c0d04

Geometry Nodes: Use UI settings for properties in modifier

The system for exposing property settings like min, max, default, subtype,
etc. for ID properties is quite convoluted currently, so I won't give a
full description here, but this commit creates the tree of ID properties
needed to store that information. This means that property subtypes like
"angle" or "XYZ" will affect the display in the modifier.

Limitations:
 - The _RNA_UI property is displayed in the modifier. This may require a
   modification to uiDefAutoButsRNA to fix.
 - IDProperties must have unique names, but node sockets don't have
   that limitation. This can be solved by adding a "UI name" field to
   IDProperties.

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

M	source/blender/makesrna/intern/rna_access.c
M	source/blender/modifiers/intern/MOD_nodes.cc

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

diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index a631fe4fc26..e71bbc6bcaf 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -1162,8 +1162,8 @@ PropertySubType RNA_property_subtype(PropertyRNA *prop)
   if (prop->magic != RNA_MAGIC) {
     IDProperty *idprop = (IDProperty *)prop;
 
-    /* Restrict to arrays only for now for performance reasons. */
-    if (idprop->type == IDP_ARRAY && ELEM(idprop->subtype, IDP_INT, IDP_FLOAT, IDP_DOUBLE)) {
+    if (ELEM(idprop->type, IDP_INT, IDP_FLOAT, IDP_DOUBLE) ||
+        ((idprop->type == IDP_ARRAY) && ELEM(idprop->subtype, IDP_INT, IDP_FLOAT, IDP_DOUBLE))) {
       const IDProperty *idp_ui = rna_idproperty_ui(prop);
 
       if (idp_ui) {
diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc
index bee37c7fdb5..436676b989d 100644
--- a/source/blender/modifiers/intern/MOD_nodes.cc
+++ b/source/blender/modifiers/intern/MOD_nodes.cc
@@ -57,6 +57,7 @@
 #include "UI_resources.h"
 
 #include "RNA_access.h"
+#include "RNA_enum_types.h"
 
 #include "DEG_depsgraph_build.h"
 #include "DEG_depsgraph_query.h"
@@ -328,21 +329,99 @@ class GeometryNodesEvaluator {
   }
 };
 
+/**
+ * This code is responsible for creating the new property and also creating the group of
+ * properties in the prop_ui_container group for the UI info, the mapping for which is
+ * scattered about in RNA_access.c.
+ *
+ * TODO(Hans): Codify this with some sort of table or refactor IDProperty use in RNA_access.c.
+ */
 struct SocketPropertyType {
-  IDProperty *(*create)(const bNodeSocket &socket, const char *name);
+  /* Create the actual propery used to store the data for the modifier. */
+  IDProperty *(*create_prop)(const bNodeSocket &socket, const char *name);
+  /* Reused to build the "soft_min" property too. */
+  IDProperty *(*create_min_ui_prop)(const bNodeSocket &socket, const char *name);
+  /* Reused to build the "soft_max" property too. */
+  IDProperty *(*create_max_ui_prop)(const bNodeSocket &socket, const char *name);
+  /* This uses the same values as #create_prop, but sometimes the type is different, so it can't
+   * be the same function. */
+  IDProperty *(*create_default_ui_prop)(const bNodeSocket &socket, const char *name);
+  PropertyType (*rna_subtype_get)(const bNodeSocket &socket);
   bool (*is_correct_type)(const IDProperty &property);
   void (*init_cpp_value)(const IDProperty &property, void *r_value);
 };
 
+static IDProperty *socket_add_property(IDProperty *settings_prop_group,
+                                       IDProperty *ui_container,
+                                       const SocketPropertyType &property_type,
+                                       const bNodeSocket &socket)
+{
+  /* Add the property actually storing the data to the modifier's group.
+   * TODO: We will need to add a separate "ui_name" field for ID properties, right now multiple
+   * sockets with the same label aren't handled properly. Either that or we could continue
+   * to use a custom layout function besides uiDefAutoButsRNA to which we can pass the correct
+   * label information. */
+  IDProperty *prop = property_type.create_prop(socket, socket.name);
+  IDP_AddToGroup(settings_prop_group, prop);
+
+  /* Make the group in the ui container group to hold the property's UI settings. */
+  IDProperty *prop_ui_group;
+  {
+    IDPropertyTemplate idprop = {0};
+    prop_ui_group = IDP_New(IDP_GROUP, &idprop, socket.name);
+    IDP_AddToGroup(ui_container, prop_ui_group);
+  }
+
+  /* Create the properties for the socket's UI settings. */
+  IDP_AddToGroup(prop_ui_group, property_type.create_min_ui_prop(socket, "min"));
+  IDP_AddToGroup(prop_ui_group, property_type.create_min_ui_prop(socket, "soft_min"));
+  IDP_AddToGroup(prop_ui_group, property_type.create_max_ui_prop(socket, "max"));
+  IDP_AddToGroup(prop_ui_group, property_type.create_max_ui_prop(socket, "soft_max"));
+  IDP_AddToGroup(prop_ui_group, property_type.create_default_ui_prop(socket, "default"));
+  if (property_type.rna_subtype_get != NULL) {
+    const char *subtype_identifier = NULL;
+    RNA_enum_identifier(rna_enum_property_subtype_items,
+                        property_type.rna_subtype_get(socket),
+                        &subtype_identifier);
+
+    if (subtype_identifier != NULL) {
+      IDPropertyTemplate idprop = {0};
+      idprop.string.str = subtype_identifier;
+      idprop.string.len = BLI_strnlen(subtype_identifier, MAX_NAME) + 1;
+      IDP_AddToGroup(prop_ui_group, IDP_New(IDP_STRING, &idprop, "subtype"));
+    }
+  }
+
+  return prop;
+}
+
 static const SocketPropertyType *get_socket_property_type(const bNodeSocket &bsocket)
 {
   switch (bsocket.type) {
     case SOCK_FLOAT: {
       static const SocketPropertyType float_type = {
           [](const bNodeSocket &socket, const char *name) {
-            IDPropertyTemplate value = {0};
-            value.f = ((bNodeSocketValueFloat *)socket.default_value)->value;
-            return IDP_New(IDP_FLOAT, &value, name);
+            bNodeSocketValueFloat *value = (bNodeSocketValueFloat *)socket.default_value;
+            IDPropertyTemplate idprop = {.f = value->value};
+            return IDP_New(IDP_FLOAT, &idprop, name);
+          },
+          [](const bNodeSocket &socket, const char *name) {
+            bNodeSocketValueFloat *value = (bNodeSocketValueFloat *)socket.default_value;
+            IDPropertyTemplate idprop = {.d = value->min};
+            return IDP_New(IDP_DOUBLE, &idprop, name);
+          },
+          [](const bNodeSocket &socket, const char *name) {
+            bNodeSocketValueFloat *value = (bNodeSocketValueFloat *)socket.default_value;
+            IDPropertyTemplate idprop = {.d = value->max};
+            return IDP_New(IDP_DOUBLE, &idprop, name);
+          },
+          [](const bNodeSocket &socket, const char *name) {
+            bNodeSocketValueFloat *value = (bNodeSocketValueFloat *)socket.default_value;
+            IDPropertyTemplate idprop = {.d = value->value};
+            return IDP_New(IDP_DOUBLE, &idprop, name);
+          },
+          [](const bNodeSocket &socket) {
+            return (PropertyType)((bNodeSocketValueFloat *)socket.default_value)->subtype;
           },
           [](const IDProperty &property) { return property.type == IDP_FLOAT; },
           [](const IDProperty &property, void *r_value) {
@@ -354,9 +433,27 @@ static const SocketPropertyType *get_socket_property_type(const bNodeSocket &bso
     case SOCK_INT: {
       static const SocketPropertyType int_type = {
           [](const bNodeSocket &socket, const char *name) {
-            IDPropertyTemplate value = {0};
-            value.i = ((bNodeSocketValueInt *)socket.default_value)->value;
-            return IDP_New(IDP_INT, &value, name);
+            bNodeSocketValueInt *value = (bNodeSocketValueInt *)socket.default_value;
+            IDPropertyTemplate idprop = {.i = value->value};
+            return IDP_New(IDP_INT, &idprop, name);
+          },
+          [](const bNodeSocket &socket, const char *name) {
+            bNodeSocketValueInt *value = (bNodeSocketValueInt *)socket.default_value;
+            IDPropertyTemplate idprop = {.i = value->min};
+            return IDP_New(IDP_INT, &idprop, name);
+          },
+          [](const bNodeSocket &socket, const char *name) {
+            bNodeSocketValueInt *value = (bNodeSocketValueInt *)socket.default_value;
+            IDPropertyTemplate idprop = {.i = value->max};
+            return IDP_New(IDP_INT, &idprop, name);
+          },
+          [](const bNodeSocket &socket, const char *name) {
+            bNodeSocketValueInt *value = (bNodeSocketValueInt *)socket.default_value;
+            IDPropertyTemplate idprop = {.i = value->value};
+            return IDP_New(IDP_INT, &idprop, name);
+          },
+          [](const bNodeSocket &socket) {
+            return (PropertyType)((bNodeSocketValueInt *)socket.default_value)->subtype;
           },
           [](const IDProperty &property) { return property.type == IDP_INT; },
           [](const IDProperty &property, void *r_value) { *(int *)r_value = IDP_Int(&property); },
@@ -366,14 +463,36 @@ static const SocketPropertyType *get_socket_property_type(const bNodeSocket &bso
     case SOCK_VECTOR: {
       static const SocketPropertyType vector_type = {
           [](const bNodeSocket &socket, const char *name) {
-            IDPropertyTemplate value = {0};
-            value.array.len = 3;
-            value.array.type = IDP_FLOAT;
-            IDProperty *property = IDP_New(IDP_ARRAY, &value, name);
-            copy_v3_v3((float *)IDP_Array(property),
-                       ((bNodeSocketValueVector *)socket.default_value)->value);
+            bNodeSocketValueVector *value = (bNodeSocketValueVector *)socket.default_value;
+            IDPropertyTemplate idprop = {0};
+            idprop.array.len = 3;
+            idprop.array.type = IDP_FLOAT;
+            IDProperty *property = IDP_New(IDP_ARRAY, &idprop, name);
+            copy_v3_v3((float *)IDP_Array(property), value->value);
             return property;
           },
+          [](const bNodeSocket &socket, const char *name) {
+            bNodeSocketValueVector *value = (bNodeSocketValueVector *)socket.default_value;
+            IDPropertyTemplate idprop = {.d = value->min};
+            return IDP_New(IDP_DOUBLE, &idprop, name);
+          },
+          [](const bNodeSocket &socket, const char *name) {
+            bNodeSocketValueVector *value = (bNodeSocketValueVector *)socket.default_value;
+            IDPropertyTemplate idprop = {.d = value->max};
+            return IDP_New(IDP_DOUBLE, &idprop, name);
+          },
+          [](const bNodeSocket &socket, const char *name) {
+            bNodeSocketValueVector *value = (bNodeSocketValueVector *)socket.default_value;
+            IDPropertyTemplate idprop = {0};
+            idprop.array.len = 3;
+            idprop.array.type = IDP_FLOAT;
+            IDProperty *property = IDP_New(IDP_ARRAY, &idprop, name);
+            copy_v3_v3((float *)IDP_Array(property), value->value);
+       

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list