[Bf-blender-cvs] [a51cc1120d6] principled-v2: Add initial version of Node Sections to keep sockets more manageable

Lukas Stockner noreply at git.blender.org
Mon Nov 28 02:33:08 CET 2022


Commit: a51cc1120d6a0dd54ffc268d78f990b44297f32c
Author: Lukas Stockner
Date:   Mon Nov 28 02:13:36 2022 +0100
Branches: principled-v2
https://developer.blender.org/rBa51cc1120d6a0dd54ffc268d78f990b44297f32c

Add initial version of Node Sections to keep sockets more manageable

Nodes can now have sections, and each socket can belong to a section.

These only affect how the node is displayed. In the Node Editor, the node first
shows all sockets without a section as usual, and following that the sections
are shown.
Each section can be expanded or collapsed, hiding the sockets inside.

Node links are still drawn if the socket they're going to is invisible -
in that case, they'll be going to the section header instead. However,
dragging them or connecting a link to a hidden socket via dragging is not
possible.

Node Groups can also have sections defined by the user, which are reflected
in their group input/output and in the group nodes that use them.

Note that the code for hidden nodes is still missing, I'm not sure yet how
to handle this there.
Also, we might eventually support drawing node properties (such as SSS type
for the principled BSDF) inside a section.
Similarly, especially for custom groups it might be nice to support nested
sections.

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

M	release/scripts/startup/bl_ui/space_node.py
M	source/blender/blenkernel/BKE_node.h
M	source/blender/blenkernel/intern/node.cc
M	source/blender/blenloader/intern/versioning_300.cc
M	source/blender/editors/space_node/node_draw.cc
M	source/blender/editors/space_node/node_edit.cc
M	source/blender/editors/space_node/node_intern.hh
M	source/blender/editors/space_node/node_ops.cc
M	source/blender/editors/space_node/node_templates.cc
M	source/blender/makesdna/DNA_node_types.h
M	source/blender/makesrna/intern/rna_nodetree.c
M	source/blender/nodes/NOD_node_declaration.hh
M	source/blender/nodes/intern/node_common.cc
M	source/blender/nodes/intern/node_declaration.cc
M	source/blender/nodes/intern/node_socket.cc
M	source/blender/nodes/shader/nodes/node_shader_bsdf_principled.cc

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

diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index da94350b428..02b9f392c7a 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -813,6 +813,18 @@ class NODE_UL_interface_sockets(bpy.types.UIList):
             layout.template_node_socket(color=color)
 
 
+class NODE_UL_interface_sections(bpy.types.UIList):
+    def draw_item(self, context, layout, _data, item, icon, _active_data, _active_propname, _index):
+        socket = item
+
+        if self.layout_type in {'DEFAULT', 'COMPACT'}:
+            row = layout.row(align=True)
+
+            row.prop(item, "name", text="", emboss=False, icon_value=icon)
+        elif self.layout_type == 'GRID':
+            layout.alignment = 'CENTER'
+
+
 class NodeTreeInterfacePanel(Panel):
 
     @classmethod
@@ -881,6 +893,7 @@ class NodeTreeInterfacePanel(Panel):
             layout.use_property_split = True
             layout.use_property_decorate = False
 
+            layout.prop_search(active_socket, "section", tree, "sections")
             layout.prop(active_socket, "name")
             # Display descriptions only for Geometry Nodes, since it's only used in the modifier panel.
             if tree.type == 'GEOMETRY':
@@ -923,6 +936,37 @@ class NODE_PT_node_tree_interface_outputs(NodeTreeInterfacePanel):
         self.draw_socket_list(context, "OUT", "outputs", "active_output")
 
 
+class NODE_PT_node_tree_interface_sections(NodeTreeInterfacePanel):
+    bl_space_type = 'NODE_EDITOR'
+    bl_region_type = 'UI'
+    bl_category = "Group"
+    bl_label = "Sections"
+
+    def draw(self, context):
+        layout = self.layout
+
+        snode = context.space_data
+        tree = snode.edit_tree
+
+        split = layout.row()
+
+        split.template_list("NODE_UL_interface_sections", "", tree, "sections", tree, "active_section")
+
+        ops_col = split.column()
+
+        add_remove_col = ops_col.column(align=True)
+        props = add_remove_col.operator("node.tree_section_add", icon='ADD', text="")
+        props = add_remove_col.operator("node.tree_section_remove", icon='REMOVE', text="")
+
+        ops_col.separator()
+
+        up_down_col = ops_col.column(align=True)
+        props = up_down_col.operator("node.tree_section_move", icon='TRIA_UP', text="")
+        props.direction = 'UP'
+        props = up_down_col.operator("node.tree_section_move", icon='TRIA_DOWN', text="")
+        props.direction = 'DOWN'
+
+
 # Grease Pencil properties
 class NODE_PT_annotation(AnnotationDataPanel, Panel):
     bl_space_type = 'NODE_EDITOR'
@@ -985,8 +1029,10 @@ classes = (
     NODE_PT_annotation,
     NODE_PT_overlay,
     NODE_UL_interface_sockets,
+    NODE_UL_interface_sections,
     NODE_PT_node_tree_interface_inputs,
     NODE_PT_node_tree_interface_outputs,
+    NODE_PT_node_tree_interface_sections,
 
     node_panel(EEVEE_MATERIAL_PT_settings),
     node_panel(MATERIAL_PT_viewport),
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index a8e28ba492a..16a584d5ecc 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -580,6 +580,9 @@ struct bNodeSocket *ntreeInsertSocketInterfaceFromSocket(struct bNodeTree *ntree
                                                          struct bNodeSocket *from_sock);
 void ntreeRemoveSocketInterface(struct bNodeTree *ntree, struct bNodeSocket *sock);
 
+struct bNodeSection *ntreeAddSection(struct bNodeTree *ntree, const char *name);
+void ntreeRemoveSection(struct bNodeTree *ntree, struct bNodeSection *section);
+
 /** \} */
 
 /* -------------------------------------------------------------------- */
@@ -662,6 +665,9 @@ void nodeModifySocketType(struct bNodeTree *ntree,
 void nodeModifySocketTypeStatic(
     struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock, int type, int subtype);
 
+struct bNodeSection *nodeAddSection(struct bNode *node, const char *name);
+void nodeRemoveSection(struct bNode *node, struct bNodeSection *section);
+
 struct bNode *nodeAddNode(const struct bContext *C, struct bNodeTree *ntree, const char *idname);
 struct bNode *nodeAddStaticNode(const struct bContext *C, struct bNodeTree *ntree, int type);
 /**
@@ -837,6 +843,8 @@ void nodeSetSocketAvailability(struct bNodeTree *ntree,
                                struct bNodeSocket *sock,
                                bool is_available);
 
+void nodeSetSectionAvailability(struct bNodeSection *section, bool is_available);
+
 int nodeSocketLinkLimit(const struct bNodeSocket *sock);
 
 /**
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index ba8938874e6..19f57dccb30 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -113,7 +113,10 @@ bNodeSocketType NodeSocketTypeUndefined;
 static CLG_LogRef LOG = {"bke.node"};
 
 static void ntree_set_typeinfo(bNodeTree *ntree, bNodeTreeType *typeinfo);
-static void node_socket_copy(bNodeSocket *sock_dst, const bNodeSocket *sock_src, const int flag);
+static void node_socket_copy(bNodeSocket *sock_dst,
+                             const bNodeSocket *sock_src,
+                             const int flag,
+                             const Map<const bNodeSection *, bNodeSection *> &section_map);
 static void free_localized_node_groups(bNodeTree *ntree);
 static void node_free_node(bNodeTree *ntree, bNode *node);
 static void node_socket_interface_free(bNodeTree * /*ntree*/,
@@ -167,17 +170,27 @@ static void ntree_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, cons
     BLI_addtail(&ntree_dst->links, dst_link);
   }
 
+  /* copy interface sections */
+  Map<const bNodeSection *, bNodeSection *> section_map;
+  section_map.add_new(nullptr, nullptr);
+  BLI_listbase_clear(&ntree_dst->sections);
+  LISTBASE_FOREACH (const bNodeSection *, src_section, &ntree_src->sections) {
+    bNodeSection *dst_section = (bNodeSection *)MEM_dupallocN(src_section);
+    BLI_addtail(&ntree_dst->sections, dst_section);
+    section_map.add_new(src_section, dst_section);
+  }
+
   /* copy interface sockets */
   BLI_listbase_clear(&ntree_dst->inputs);
   LISTBASE_FOREACH (const bNodeSocket *, src_socket, &ntree_src->inputs) {
     bNodeSocket *dst_socket = (bNodeSocket *)MEM_dupallocN(src_socket);
-    node_socket_copy(dst_socket, src_socket, flag_subdata);
+    node_socket_copy(dst_socket, src_socket, flag_subdata, section_map);
     BLI_addtail(&ntree_dst->inputs, dst_socket);
   }
   BLI_listbase_clear(&ntree_dst->outputs);
   LISTBASE_FOREACH (const bNodeSocket *, src_socket, &ntree_src->outputs) {
     bNodeSocket *dst_socket = (bNodeSocket *)MEM_dupallocN(src_socket);
-    node_socket_copy(dst_socket, src_socket, flag_subdata);
+    node_socket_copy(dst_socket, src_socket, flag_subdata, section_map);
     BLI_addtail(&ntree_dst->outputs, dst_socket);
   }
 
@@ -256,6 +269,8 @@ static void ntree_free_data(ID *id)
     MEM_freeN(sock);
   }
 
+  BLI_freelistN(&ntree->sections);
+
   /* free preview hash */
   if (ntree->previews) {
     BKE_node_instance_hash_free(ntree->previews, (bNodeInstanceValueFP)BKE_node_preview_free);
@@ -504,6 +519,10 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
       IDP_BlendWrite(writer, node->prop);
     }
 
+    LISTBASE_FOREACH (bNodeSection *, section, &node->sections) {
+      BLO_write_struct(writer, bNodeSection, section);
+    }
+
     LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
       write_node_socket(writer, sock);
     }
@@ -600,6 +619,10 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree)
     BLO_write_struct(writer, bNodeLink, link);
   }
 
+  LISTBASE_FOREACH (bNodeSection *, section, &ntree->sections) {
+    BLO_write_struct(writer, bNodeSection, section);
+  }
+
   LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->inputs) {
     write_node_socket_interface(writer, sock);
   }
@@ -681,10 +704,18 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
 
     BLO_read_list(reader, &node->inputs);
     BLO_read_list(reader, &node->outputs);
+    BLO_read_list(reader, &node->sections);
 
     BLO_read_data_address(reader, &node->prop);
     IDP_BlendDataRead(reader, &node->prop);
 
+    LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
+      BLO_read_data_address(reader, &sock->section);
+    }
+    LISTBASE_FOREACH (bNodeSocket *, sock, &node->outputs) {
+      BLO_read_data_address(reader, &sock->section);
+    }
+
     if (node->type == CMP_NODE_MOVIEDISTORTION) {
       /* Do nothing, this is runtime cache and hence handled by generic code using
        * `IDTypeInfo.foreach_cache` callback. */
@@ -788,10 +819,13 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
   /* interface socket lists */
   BLO_read_list(reader, &ntree->inputs);
   BLO_read_list(reader, &ntree->outputs);
+  BLO_read_list(reader, &ntree->sections);
   LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->inputs) {
+    BLO_read_data_address(reader, &sock->section);
     direct_link_node_socket(reader, sock);
   }
   LISTBASE_FOREACH (bNodeSocket *, sock, &ntree->outputs) {
+    BLO_read_data_address(reader, &sock->section);
     direct_link_node_socket(reader, sock);
   }
 
@@ -2005,6 +2039,39 @@ void nodeRemoveAllSockets(bNodeTree *ntree, bNode *node)
   BKE_ntree_update_tag_socket_removed(ntree);
 }
 
+struct bNodeSection *nodeAddSection(struct bNode *node, const char *name)
+{
+  bNodeSection *section = MEM_cnew<bNodeSection>("section");
+  BLI_strncpy(section->name, name, NODE_MAXSTR);
+  section->flag = NODE_SECTION_CLOSED;
+
+  BLI_addtail(&node->sections, section);
+  BLI_uniquename(&node->sections,
+                 section,
+                 DATA_("Section"),
+                 '.',
+                 offsetof(bNodeSection, name),
+                 sizeof(section->name));
+  return section;
+}
+
+void nodeRemoveSection(struct bNode *node, struct bNodeSection *section)
+{
+  LISTBASE_FOREACH (bNodeSocket *, sock, &node->inputs) {
+    if (sock->section == section) {
+      sock->section = nullptr;
+    }
+  }
+  LISTBASE_FOREAC

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list