[Bf-blender-cvs] [3dfc3df1a4f] temp-compact-node-prototype: initial expose code

Jacques Lucke noreply at git.blender.org
Thu Mar 25 16:11:05 CET 2021


Commit: 3dfc3df1a4fde1e85690c8d7c424ac0b8fbdd107
Author: Jacques Lucke
Date:   Thu Mar 25 10:03:59 2021 +0100
Branches: temp-compact-node-prototype
https://developer.blender.org/rB3dfc3df1a4fde1e85690c8d7c424ac0b8fbdd107

initial expose code

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

M	release/scripts/startup/bl_operators/node.py
M	source/blender/nodes/CMakeLists.txt
A	source/blender/nodes/NOD_ui_layout.hh
M	source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc

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

diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py
index 7884a7287b7..52484f8ffc8 100644
--- a/release/scripts/startup/bl_operators/node.py
+++ b/release/scripts/startup/bl_operators/node.py
@@ -303,6 +303,27 @@ class NODE_OT_tree_path_parent(Operator):
         return {'FINISHED'}
 
 
+class NODE_OT_expose_input_socket(Operator):
+    '''Expose socket'''
+    bl_idname = "node.expose_input_socket"
+    bl_label = "Expose Input Socket"
+
+    tree_name: StringProperty()
+    node_name: StringProperty()
+    # Might reference multiple sockets intentionally.
+    socket_name: StringProperty()
+
+    expose: BoolProperty(default=True)
+
+    def execute(self, context):
+        tree = bpy.data.node_groups[self.tree_name]
+        node = tree.nodes[self.node_name]
+        for socket in node.inputs:
+            if socket.name == self.socket_name:
+                socket.hide = not self.expose
+        return {'FINISHED'}
+
+
 classes = (
     NodeSetting,
 
@@ -311,4 +332,5 @@ classes = (
     NODE_OT_add_search,
     NODE_OT_collapse_hide_unused_toggle,
     NODE_OT_tree_path_parent,
+    NODE_OT_expose_input_socket,
 )
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 271f4e5c5e4..42679f39f18 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -38,6 +38,7 @@ set(INC
   ../makesdna
   ../makesrna
   ../render
+  ../windowmanager
   ../../../intern/glew-mx
   ../../../intern/guardedalloc
   ../../../intern/sky/include
diff --git a/source/blender/nodes/NOD_ui_layout.hh b/source/blender/nodes/NOD_ui_layout.hh
new file mode 100644
index 00000000000..b70969a7677
--- /dev/null
+++ b/source/blender/nodes/NOD_ui_layout.hh
@@ -0,0 +1,21 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#pragma once
+
+namespace blender::nodes {
+
+}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc b/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc
index 2139c5afa6b..eea2f8ad9f9 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_attribute_fill.cc
@@ -24,6 +24,8 @@
 #include "UI_interface.h"
 #include "UI_resources.h"
 
+#include "WM_types.h"
+
 static bNodeSocketTemplate geo_node_attribute_fill_in[] = {
     {SOCK_GEOMETRY, N_("Geometry")},
     {SOCK_STRING, N_("Attribute")},
@@ -40,14 +42,6 @@ static bNodeSocketTemplate geo_node_attribute_fill_out[] = {
     {-1, ""},
 };
 
-static void geo_node_attribute_fill_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
-{
-  uiLayoutSetPropSep(layout, true);
-  uiLayoutSetPropDecorate(layout, false);
-  uiItemR(layout, ptr, "domain", 0, "", ICON_NONE);
-  uiItemR(layout, ptr, "data_type", 0, "", ICON_NONE);
-}
-
 static void geo_node_attribute_fill_init(bNodeTree *UNUSED(tree), bNode *node)
 {
   node->custom1 = CD_PROP_FLOAT;
@@ -73,6 +67,123 @@ static void geo_node_attribute_fill_update(bNodeTree *UNUSED(ntree), bNode *node
 
 namespace blender::nodes {
 
+template<typename T1, typename T2, typename T3>
+uint64_t default_hash_3(const T1 &v1, const T2 &v2, const T3 &v3)
+{
+  const uint64_t h1 = DefaultHash<T1>{}(v1);
+  const uint64_t h2 = DefaultHash<T2>{}(v2);
+  const uint64_t h3 = DefaultHash<T3>{}(v3);
+  return (h1 * 73856093) ^ (h2 * 19349663) ^ (h3 * 83492791);
+}
+
+namespace {
+
+struct SocketMenuInfo {
+  bNodeTree *ntree;
+  bNode *node;
+  bNodeSocket *socket;
+};
+
+struct SocketMenuInfoPtr {
+  std::unique_ptr<SocketMenuInfo> value;
+
+  friend bool operator==(const SocketMenuInfoPtr &a, const SocketMenuInfoPtr &b)
+  {
+    return a.value->ntree == b.value->ntree && a.value->node == b.value->node &&
+           a.value->socket == b.value->socket;
+  }
+
+  uint64_t hash() const
+  {
+    return default_hash_3(value->ntree, value->node, value->socket);
+  }
+};
+}  // namespace
+
+static Set<SocketMenuInfoPtr> &get_socket_menu_info_set()
+{
+  static Set<SocketMenuInfoPtr> set;
+  return set;
+}
+
+static void draw_socket_menu(bContext *C, uiLayout *layout, void *arg)
+{
+  SocketMenuInfo *socket_info = (SocketMenuInfo *)arg;
+  uiItemL(layout, socket_info->node->name, ICON_NONE);
+  uiItemL(layout, socket_info->socket->name, ICON_NONE);
+
+  PointerRNA node_ptr;
+  RNA_pointer_create(&socket_info->ntree->id, &RNA_Node, socket_info->node, &node_ptr);
+  PointerRNA socket_ptr;
+  RNA_pointer_create(&socket_info->ntree->id, &RNA_NodeSocket, socket_info->socket, &socket_ptr);
+
+  // uiItemR(layout, &socket_ptr, "hide", 0, "Expose", ICON_NONE);
+
+  if (socket_info->socket->flag & SOCK_HIDDEN) {
+    PointerRNA expose_props;
+    uiItemFullO(layout,
+                "node.expose_input_socket",
+                "Expose",
+                ICON_NONE,
+                nullptr,
+                WM_OP_EXEC_DEFAULT,
+                0,
+                &expose_props);
+    RNA_string_set(&expose_props, "tree_name", socket_info->ntree->id.name + 2);
+    RNA_string_set(&expose_props, "node_name", socket_info->node->name);
+    RNA_string_set(&expose_props, "socket_name", socket_info->socket->name);
+    RNA_boolean_set(&expose_props, "expose", true);
+  }
+  else {
+    PointerRNA expose_props;
+    uiItemFullO(layout,
+                "node.expose_input_socket",
+                "Unexpose",
+                ICON_NONE,
+                nullptr,
+                WM_OP_EXEC_DEFAULT,
+                0,
+                &expose_props);
+    RNA_string_set(&expose_props, "tree_name", socket_info->ntree->id.name + 2);
+    RNA_string_set(&expose_props, "node_name", socket_info->node->name);
+    RNA_string_set(&expose_props, "socket_name", socket_info->socket->name);
+    RNA_boolean_set(&expose_props, "expose", false);
+  }
+}
+
+static void geo_node_attribute_fill_layout(uiLayout *layout, bContext *C, PointerRNA *node_ptr)
+{
+  bNodeTree *ntree = (bNodeTree *)node_ptr->owner_id;
+  bNode *node = (bNode *)node_ptr->data;
+  bNodeSocket *socket = (bNodeSocket *)BLI_findlink(&node->inputs, 3);
+
+  PointerRNA socket_ptr;
+  RNA_pointer_create(node_ptr->owner_id, &RNA_NodeSocket, socket, &socket_ptr);
+
+  uiItemR(layout, node_ptr, "domain", 0, "", ICON_NONE);
+  uiItemR(layout, node_ptr, "data_type", 0, "", ICON_NONE);
+
+  Set<SocketMenuInfoPtr> &set = get_socket_menu_info_set();
+  {
+    auto info = SocketMenuInfoPtr{std::make_unique<SocketMenuInfo>()};
+    info.value->ntree = ntree;
+    info.value->node = node;
+    info.value->socket = socket;
+    set.add(std::move(info));
+  }
+  auto info = SocketMenuInfoPtr{std::make_unique<SocketMenuInfo>()};
+  info.value->ntree = ntree;
+  info.value->node = node;
+  info.value->socket = socket;
+  SocketMenuInfo *stored_info = set.lookup_key(info).value.get();
+
+  uiLayout *row = uiLayoutRow(layout, false);
+  uiLayout *sub_row = uiLayoutRow(row, false);
+  uiLayoutSetActive(sub_row, (socket->flag & SOCK_HIDDEN) != 0);
+  socket->typeinfo->draw(C, sub_row, &socket_ptr, node_ptr, "");
+  uiItemMenuF(row, "", ICON_DOWNARROW_HLT, draw_socket_menu, stored_info);
+}
+
 static AttributeDomain get_result_domain(const GeometryComponent &component,
                                          StringRef attribute_name)
 {
@@ -168,6 +279,6 @@ void register_node_type_geo_attribute_fill()
   node_type_init(&ntype, geo_node_attribute_fill_init);
   node_type_update(&ntype, geo_node_attribute_fill_update);
   ntype.geometry_node_execute = blender::nodes::geo_node_attribute_fill_exec;
-  ntype.draw_buttons = geo_node_attribute_fill_layout;
+  ntype.draw_buttons = blender::nodes::geo_node_attribute_fill_layout;
   nodeRegisterType(&ntype);
 }



More information about the Bf-blender-cvs mailing list