From 909430f5dc64f54b87a2c5482add4820eed42d28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Tue, 6 Jun 2023 11:10:41 +0200 Subject: [PATCH 01/22] Category declarations in node trees for organizing modifier UI. Adds an optional list of "categories" to node trees. Each socket can be assigned a category. Sub-panels will be created in the future for these categories (TODO). Sockets of the same category will remain together even when adding, removing, or moving sockets or categories, renaming, etc. A socket can be moved up or down within a category but each category remains a contiguous block. Actual tree views may be created later. --- scripts/startup/bl_operators/node.py | 83 ++++++ scripts/startup/bl_ui/space_node.py | 60 +++++ source/blender/CMakeLists.txt | 1 + source/blender/blenkernel/BKE_node.h | 55 +++- source/blender/blenkernel/BKE_node_runtime.hh | 10 + source/blender/blenkernel/intern/node.cc | 214 ++++++++++++++++ .../blenloader/intern/versioning_400.cc | 16 +- source/blender/editors/space_node/drawnode.cc | 5 + .../blender/editors/space_node/node_edit.cc | 4 + source/blender/makesdna/DNA_node_defaults.h | 23 ++ source/blender/makesdna/DNA_node_types.h | 18 ++ source/blender/makesdna/intern/dna_defaults.c | 1 + source/blender/makesrna/intern/rna_nodetree.c | 239 ++++++++++++++++++ 13 files changed, 724 insertions(+), 5 deletions(-) create mode 100644 source/blender/makesdna/DNA_node_defaults.h diff --git a/scripts/startup/bl_operators/node.py b/scripts/startup/bl_operators/node.py index 9c1b14c6ae5..de5990c7806 100644 --- a/scripts/startup/bl_operators/node.py +++ b/scripts/startup/bl_operators/node.py @@ -9,6 +9,7 @@ from bpy.types import ( from bpy.props import ( BoolProperty, CollectionProperty, + EnumProperty, FloatVectorProperty, StringProperty, ) @@ -243,11 +244,93 @@ class NODE_OT_tree_path_parent(Operator): return {'FINISHED'} +class NodeSocketCategoryOperator(): + @classmethod + def poll(cls, context): + snode = context.space_data + if snode is None: + return False + tree = snode.edit_tree + if tree is None: + return False + if tree.is_embedded_data: + return False + return True + + +class NODE_OT_socket_category_add(NodeSocketCategoryOperator, Operator): + '''Add a new socket category to the tree''' + bl_idname = "node.function_parameter_add" + bl_label = "Add Socket Category" + bl_options = {'REGISTER', 'UNDO'} + + def execute(self, context): + snode = context.space_data + tree = snode.edit_tree + categories = tree.socket_categories + + # Remember index to move the item + dst_index = min(categories.active_index + 1, len(categories)) + categories.new("Category") + categories.move(len(categories) - 1, dst_index) + categories.active_index = dst_index + + return {'FINISHED'} + + +class NODE_OT_socket_category_remove(NodeSocketCategoryOperator, Operator): + '''Remove a socket category from the tree''' + bl_idname = "node.function_parameter_remove" + bl_label = "Remove Socket Category" + bl_options = {'REGISTER', 'UNDO'} + + def execute(self, context): + snode = context.space_data + tree = snode.edit_tree + categories = tree.socket_categories + + if categories.active: + categories.remove(categories.active) + categories.active_index = min(categories.active_index, len(categories) - 1) + + return {'FINISHED'} + + +class NODE_OT_socket_category_move(NodeSocketCategoryOperator, Operator): + '''Move a socket category to another position''' + bl_idname = "node.function_parameter_move" + bl_label = "Move Socket Category" + bl_options = {'REGISTER', 'UNDO'} + + direction: EnumProperty( + name="Direction", + items=[('UP', "Up", ""), ('DOWN', "Down", "")], + default = 'UP', + ) + + def execute(self, context): + snode = context.space_data + tree = snode.edit_tree + categories = tree.socket_categories + + if self.direction == 'UP' and categories.active_index > 0: + categories.move(categories.active_index, categories.active_index - 1) + categories.active_index -= 1 + elif self.direction == 'DOWN' and categories.active_index < len(categories) - 1: + categories.move(categories.active_index, categories.active_index + 1) + categories.active_index += 1 + + return {'FINISHED'} + + classes = ( NodeSetting, NODE_OT_add_node, NODE_OT_add_simulation_zone, NODE_OT_collapse_hide_unused_toggle, + NODE_OT_socket_category_add, + NODE_OT_socket_category_remove, + NODE_OT_socket_category_move, NODE_OT_tree_path_parent, ) diff --git a/scripts/startup/bl_ui/space_node.py b/scripts/startup/bl_ui/space_node.py index 7f3c6c913c0..242936b811f 100644 --- a/scripts/startup/bl_ui/space_node.py +++ b/scripts/startup/bl_ui/space_node.py @@ -954,6 +954,64 @@ class NODE_PT_node_tree_interface_outputs(NodeTreeInterfacePanel): self.draw_socket_list(context, "OUT", "outputs", "active_output") +class NODE_UL_socket_categories(bpy.types.UIList): + def draw_item(self, context, layout, _data, item, icon, _active_data, _active_propname, _index): + row = layout.row(align=True) + row.prop(item, "name", text="", emboss=False, icon_value=icon) + + +class NODE_PT_socket_categories(Panel): + bl_space_type = 'NODE_EDITOR' + bl_region_type = 'UI' + bl_category = "Group" + bl_label = "Socket Categories" + + @classmethod + def poll(cls, context): + snode = context.space_data + if snode is None: + return False + tree = snode.edit_tree + if tree is None: + return False + if tree.is_embedded_data: + return False + return True + + def draw(self, context): + layout = self.layout + snode = context.space_data + tree = snode.edit_tree + + split = layout.row() + + split.template_list( + "NODE_UL_socket_categories", + "", + tree, + "socket_categories", + tree.socket_categories, + "active_index") + + ops_col = split.column() + + add_remove_col = ops_col.column(align=True) + add_remove_col.operator("node.function_parameter_add", icon='ADD', text="") + add_remove_col.operator("node.function_parameter_remove", icon='REMOVE', text="") + + ops_col.separator() + + up_down_col = ops_col.column(align=True) + props = up_down_col.operator("node.function_parameter_move", icon='TRIA_UP', text="") + props.direction = 'UP' + props = up_down_col.operator("node.function_parameter_move", icon='TRIA_DOWN', text="") + props.direction = 'DOWN' + + active_category = tree.socket_categories.active + if active_category is not None: + layout.prop(active_category, "name") + + class NODE_UL_simulation_zone_items(bpy.types.UIList): def draw_item(self, context, layout, _data, item, icon, _active_data, _active_propname, _index): if self.layout_type in {'DEFAULT', 'COMPACT'}: @@ -1097,6 +1155,8 @@ classes = ( NODE_UL_interface_sockets, NODE_PT_node_tree_interface_inputs, NODE_PT_node_tree_interface_outputs, + NODE_UL_socket_categories, + NODE_PT_socket_categories, NODE_UL_simulation_zone_items, NODE_PT_simulation_zone_items, diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index 3f0fc409a44..b17501c8bb1 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -115,6 +115,7 @@ set(SRC_DNA_DEFAULTS_INC ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_meta_defaults.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_modifier_defaults.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_movieclip_defaults.h + ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_node_defaults.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_defaults.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_particle_defaults.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_pointcloud_defaults.h diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 4cce5f6a262..8b408847164 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -542,6 +542,12 @@ void ntreeBlendWrite(struct BlendWriter *writer, struct bNodeTree *ntree); /** \name Node Tree Interface * \{ */ +/** + * Run this after relevant changes to categories + * to ensure sockets remain sorted by category. + */ +void ntreeEnsureSocketCategoryOrder(bNodeTree *ntree); + void ntreeRemoveSocketInterface(bNodeTree *ntree, bNodeSocket *sock); struct bNodeSocket *ntreeAddSocketInterface(struct bNodeTree *ntree, @@ -549,6 +555,47 @@ struct bNodeSocket *ntreeAddSocketInterface(struct bNodeTree *ntree, const char *idname, const char *name); +/** Set the category of the interface socket. */ +void ntreeSetSocketInterfaceCategory(bNodeTree *ntree, + bNodeSocket *sock, + bNodeSocketCategory *category); + +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Node Tree Socket Categories + * \{ */ + +/** + * Add a new socket category to the node tree. + * \param name Name of the new category. + * \param name Flags of the new category. + */ +bNodeSocketCategory *ntreeAddSocketCategory(bNodeTree *ntree, const char *name, int flag); + +/** + * Insert a new socket category in the node tree. + * \param name Name of the new category. + * \param name Flags of the new category. + * \param index Index at which to insert the category. + */ +bNodeSocketCategory *ntreeInsertSocketCategory(bNodeTree *ntree, + const char *name, + int flag, + int index); + +/** Remove a socket category from the node tree. */ +void ntreeRemoveSocketCategory(bNodeTree *ntree, bNodeSocketCategory *category); + +/** Remove all socket categories from the node tree. */ +void ntreeClearSocketCategories(bNodeTree *ntree); + +/** + * Move a socket category up or down in the node tree. + * \param index Index to which to move the category. + */ +void ntreeMoveSocketCategory(bNodeTree *ntree, bNodeSocketCategory *category, int new_index); + /** \} */ /* -------------------------------------------------------------------- */ @@ -867,16 +914,16 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i /* NOTE: types are needed to restore callbacks, don't change values. */ -//#define SH_NODE_MATERIAL 100 +// #define SH_NODE_MATERIAL 100 #define SH_NODE_RGB 101 #define SH_NODE_VALUE 102 #define SH_NODE_MIX_RGB_LEGACY 103 #define SH_NODE_VALTORGB 104 #define SH_NODE_RGBTOBW 105 #define SH_NODE_SHADERTORGB 106 -//#define SH_NODE_TEXTURE 106 +// #define SH_NODE_TEXTURE 106 #define SH_NODE_NORMAL 107 -//#define SH_NODE_GEOMETRY 108 +// #define SH_NODE_GEOMETRY 108 #define SH_NODE_MAPPING 109 #define SH_NODE_CURVE_VEC 110 #define SH_NODE_CURVE_RGB 111 @@ -884,7 +931,7 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i #define SH_NODE_MATH 115 #define SH_NODE_VECTOR_MATH 116 #define SH_NODE_SQUEEZE 117 -//#define SH_NODE_MATERIAL_EXT 118 +// #define SH_NODE_MATERIAL_EXT 118 #define SH_NODE_INVERT 119 #define SH_NODE_SEPRGB_LEGACY 120 #define SH_NODE_COMBRGB_LEGACY 121 diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index 3962c0c96b8..8969f91ba91 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -516,6 +516,16 @@ inline blender::Span bNodeTree::root_frames() const return this->runtime->root_frames; } +inline blender::Span bNodeTree::socket_categories() const +{ + return blender::Span(socket_categories_array, socket_categories_num); +} + +inline blender::MutableSpan bNodeTree::socket_categories_for_write() +{ + return blender::MutableSpan(socket_categories_array, socket_categories_num); +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index dfb8bfce90c..c1447f88216 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -645,6 +645,12 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree) write_node_socket_interface(writer, sock); } + BLO_write_struct_array( + writer, bNodeSocketCategory, ntree->socket_categories_num, ntree->socket_categories_array); + for (const bNodeSocketCategory &category : ntree->socket_categories()) { + BLO_write_string(writer, category.name); + } + BKE_previewimg_blend_write(writer, ntree->preview); } @@ -865,6 +871,11 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree) BLO_read_data_address(reader, &link->tosock); } + BLO_read_data_address(reader, &ntree->socket_categories_array); + for (bNodeSocketCategory &category : ntree->socket_categories_for_write()) { + BLO_read_data_address(reader, &category.name); + } + /* TODO: should be dealt by new generic cache handling of IDs... */ ntree->previews = nullptr; @@ -3647,10 +3658,18 @@ static bNodeSocket *make_socket_interface(bNodeTree *ntree, STRNCPY(sock->name, name); sock->storage = nullptr; sock->flag |= SOCK_COLLAPSED; + sock->category_index = -1; return sock; } +static int node_socket_category_cmp(const void *a, const void *b) +{ + const bNodeSocket *sock_a = static_cast(a); + const bNodeSocket *sock_b = static_cast(b); + return (sock_a->category_index > sock_b->category_index) ? 1 : 0; +} + bNodeSocket *ntreeFindSocketInterface(bNodeTree *ntree, const eNodeSocketInOut in_out, const char *identifier) @@ -3666,6 +3685,12 @@ bNodeSocket *ntreeFindSocketInterface(bNodeTree *ntree, } // namespace blender::bke +void ntreeEnsureSocketCategoryOrder(bNodeTree *ntree) +{ + BLI_listbase_sort(&ntree->inputs, blender::bke::node_socket_category_cmp); + BLI_listbase_sort(&ntree->outputs, blender::bke::node_socket_category_cmp); +} + bNodeSocket *ntreeAddSocketInterface(bNodeTree *ntree, const eNodeSocketInOut in_out, const char *idname, @@ -3678,10 +3703,30 @@ bNodeSocket *ntreeAddSocketInterface(bNodeTree *ntree, else if (in_out == SOCK_OUT) { BLI_addtail(&ntree->outputs, iosock); } + + ntreeEnsureSocketCategoryOrder(ntree); + BKE_ntree_update_tag_interface(ntree); return iosock; } +void ntreeSetSocketInterfaceCategory(bNodeTree *ntree, + bNodeSocket *socket, + bNodeSocketCategory *category) +{ + if (category == NULL) { + socket->category_index = -1; + return; + } + + socket->category_index = category - ntree->socket_categories_array; + BLI_assert(ntree->socket_categories().index_range().contains(socket->category_index)); + + ntreeEnsureSocketCategoryOrder(ntree); + + BKE_ntree_update_tag_interface(ntree); +} + namespace blender::bke { bNodeSocket *ntreeInsertSocketInterface(bNodeTree *ntree, @@ -3697,6 +3742,9 @@ bNodeSocket *ntreeInsertSocketInterface(bNodeTree *ntree, else if (in_out == SOCK_OUT) { BLI_insertlinkbefore(&ntree->outputs, next_sock, iosock); } + + ntreeEnsureSocketCategoryOrder(ntree); + BKE_ntree_update_tag_interface(ntree); return iosock; } @@ -3752,11 +3800,177 @@ void ntreeRemoveSocketInterface(bNodeTree *ntree, bNodeSocket *sock) blender::bke::node_socket_interface_free(ntree, sock, true); MEM_freeN(sock); + /* No need to resort by category, removing doesn't change anything. */ + BKE_ntree_update_tag_interface(ntree); } namespace blender::bke { +/* Fix socket category indices after changes. */ +static void remap_socket_categories(bNodeTree &ntree, std::function index_fn) +{ + LISTBASE_FOREACH (bNodeSocket *, socket, &ntree.inputs) { + socket->category_index = index_fn(socket->category_index); + BLI_assert(socket->category_index == -1 || + ntree.socket_categories().index_range().contains(socket->category_index)); + } + LISTBASE_FOREACH (bNodeSocket *, socket, &ntree.outputs) { + socket->category_index = index_fn(socket->category_index); + BLI_assert(socket->category_index == -1 || + ntree.socket_categories().index_range().contains(socket->category_index)); + } +} + +} // namespace blender::bke + +bNodeSocketCategory *ntreeAddSocketCategory(bNodeTree *ntree, const char *name, int flag) +{ + bNodeSocketCategory *old_categories_array = ntree->socket_categories_array; + const Span old_categories = ntree->socket_categories(); + ntree->socket_categories_array = MEM_cnew_array( + ntree->socket_categories_num + 1, "socket categories"); + ++ntree->socket_categories_num; + const MutableSpan new_categories = ntree->socket_categories_for_write(); + + for (const int i : new_categories.index_range().drop_back(1)) { + new_categories[i] = old_categories[i]; + } + bNodeSocketCategory &new_category = new_categories[new_categories.size() - 1]; + new_category = {BLI_strdup(name), flag}; + + MEM_SAFE_FREE(old_categories_array); + + /* No need to remap socket categories, in this case old indices stay the same. */ + /* No need to sort sockets, nothing is using the new category yet */ + + return &new_category; +} + +bNodeSocketCategory *ntreeInsertSocketCategory(bNodeTree *ntree, + const char *name, + int flag, + int index) +{ + if (!blender::IndexRange(ntree->socket_categories().size() + 1).contains(index)) { + return nullptr; + } + + bNodeSocketCategory *old_categories_array = ntree->socket_categories_array; + const Span old_categories = ntree->socket_categories(); + ntree->socket_categories_array = MEM_cnew_array( + ntree->socket_categories_num + 1, "socket categories"); + ++ntree->socket_categories_num; + const MutableSpan new_categories = ntree->socket_categories_for_write(); + + for (const int i : new_categories.index_range().take_front(index)) { + new_categories[i] = old_categories[i]; + } + for (const int i : new_categories.index_range().drop_front(index)) { + new_categories[i + 1] = old_categories[i]; + } + bNodeSocketCategory &new_category = new_categories[index]; + new_category = {BLI_strdup(name), flag}; + + MEM_SAFE_FREE(old_categories_array); + + blender::bke::remap_socket_categories(*ntree, [index](const int old_category_index) { + return old_category_index < index ? old_category_index : old_category_index + 1; + }); + + /* No need to sort sockets, nothing is using the new category yet */ + + return &new_category; +} + +void ntreeRemoveSocketCategory(bNodeTree *ntree, bNodeSocketCategory *category) +{ + const int index = category - ntree->socket_categories_array; + if (!ntree->socket_categories().contains_ptr(category)) { + return; + } + + bNodeSocketCategory *old_categories_array = ntree->socket_categories_array; + const Span old_categories = ntree->socket_categories(); + ntree->socket_categories_array = MEM_cnew_array( + ntree->socket_categories_num - 1, "socket categories"); + --ntree->socket_categories_num; + const MutableSpan new_categories = ntree->socket_categories_for_write(); + + for (const int i : new_categories.index_range().take_front(index)) { + new_categories[i] = old_categories[i]; + } + for (const int i : new_categories.index_range().drop_front(index)) { + new_categories[i] = old_categories[i + 1]; + } + + MEM_SAFE_FREE(old_categories_array); + + blender::bke::remap_socket_categories(*ntree, [index](const int old_category_index) { + return old_category_index < index ? old_category_index : + (old_category_index > index ? old_category_index - 1 : -1); + }); + + ntreeEnsureSocketCategoryOrder(ntree); +} + +void ntreeClearSocketCategories(bNodeTree *ntree) +{ + MEM_SAFE_FREE(ntree->socket_categories_array); + ntree->socket_categories_array = nullptr; + ntree->socket_categories_num = 0; + + blender::bke::remap_socket_categories(*ntree, [](const int /*old_index*/) { return -1; }); + + /* No need to sort sockets, only null category exists, relative order remains unchanged. */ +} + +void ntreeMoveSocketCategory(bNodeTree *ntree, bNodeSocketCategory *category, int new_index) +{ + const int old_index = category - ntree->socket_categories_array; + if (!ntree->socket_categories().contains_ptr(category)) { + return; + } + + const MutableSpan categories = ntree->socket_categories_for_write(); + + if (old_index == new_index) { + return; + } + else if (old_index < new_index) { + const bNodeSocketCategory tmp = categories[old_index]; + for (int i = old_index; i < new_index; ++i) { + categories[i] = categories[i + 1]; + } + categories[new_index] = tmp; + + blender::bke::remap_socket_categories( + *ntree, [old_index, new_index](const int old_category_index) { + return old_category_index < old_index || old_category_index > new_index ? + old_category_index : + (old_category_index == old_index ? new_index : old_category_index - 1); + }); + } + else /* old_index > new_index */ { + const bNodeSocketCategory tmp = categories[old_index]; + for (int i = old_index; i > new_index; --i) { + categories[i] = categories[i - 1]; + } + categories[new_index] = tmp; + + blender::bke::remap_socket_categories( + *ntree, [old_index, new_index](const int old_category_index) { + return old_category_index < new_index || old_category_index > old_index ? + old_category_index : + (old_category_index == old_index ? new_index : old_category_index + 1); + }); + } + + ntreeEnsureSocketCategoryOrder(ntree); +} + +namespace blender::bke { + static bool ntree_contains_tree_exec(const bNodeTree *tree_to_search_in, const bNodeTree *tree_to_search_for, Set &already_passed) diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index 0d1d80b7a5a..5d474b76202 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -12,6 +12,8 @@ #include "DNA_movieclip_types.h" +#include "DNA_genfile.h" + #include "BLI_assert.h" #include "BLI_listbase.h" #include "BLI_set.hh" @@ -101,7 +103,7 @@ static void version_geometry_nodes_add_realize_instance_nodes(bNodeTree *ntree) } } -void blo_do_versions_400(FileData * /*fd*/, Library * /*lib*/, Main *bmain) +void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) { if (!MAIN_VERSION_ATLEAST(bmain, 400, 1)) { LISTBASE_FOREACH (Mesh *, mesh, &bmain->meshes) { @@ -135,5 +137,17 @@ void blo_do_versions_400(FileData * /*fd*/, Library * /*lib*/, Main *bmain) */ { /* Keep this block, even when empty. */ + + if (!DNA_struct_elem_find(fd->filesdna, "bNodeSocket", "int", "category_index")) { + FOREACH_NODETREE_BEGIN (bmain, ntree, id) { + LISTBASE_FOREACH (bNodeSocket *, socket, &ntree->inputs) { + socket->category_index = -1; + } + LISTBASE_FOREACH (bNodeSocket *, socket, &ntree->outputs) { + socket->category_index = -1; + } + } + FOREACH_NODETREE_END; + } } } diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index 8d7cb6fa7a2..dce1046719f 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -1433,6 +1433,9 @@ static void std_node_socket_interface_draw(bContext * /*C*/, uiLayout *layout, P bNodeSocket *sock = (bNodeSocket *)ptr->data; int type = sock->typeinfo->type; + PointerRNA tree_ptr; + RNA_id_pointer_create(ptr->owner_id, &tree_ptr); + uiLayout *col = uiLayoutColumn(layout, false); switch (type) { @@ -1477,6 +1480,8 @@ static void std_node_socket_interface_draw(bContext * /*C*/, uiLayout *layout, P if (sock->in_out == SOCK_IN && node_tree->type == NTREE_GEOMETRY) { uiItemR(col, ptr, "hide_in_modifier", DEFAULT_FLAGS, nullptr, 0); } + + uiItemPointerR(col, ptr, "category", &tree_ptr, "socket_categories", nullptr, 0); } static void node_socket_virtual_draw_color(bContext * /*C*/, diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 663ccc095a0..cfd0effa141 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -2191,6 +2191,8 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op) ntree, in_out, active_sock->idname, active_sock->next, active_sock->name); /* XXX this only works for actual sockets, not interface templates! */ // nodeSocketCopyValue(sock, &ntree_ptr, active_sock, &ntree_ptr); + /* Inherit socket category from the active socket interface. */ + sock->category_index = active_sock->category_index; } else { /* XXX TODO: define default socket type for a tree! */ @@ -2582,6 +2584,8 @@ static int ntree_socket_move_exec(bContext *C, wmOperator *op) } } + ntreeEnsureSocketCategoryOrder(ntree); + BKE_ntree_update_tag_interface(ntree); ED_node_tree_propagate_change(C, CTX_data_main(C), ntree); diff --git a/source/blender/makesdna/DNA_node_defaults.h b/source/blender/makesdna/DNA_node_defaults.h new file mode 100644 index 00000000000..1b528a2e5b5 --- /dev/null +++ b/source/blender/makesdna/DNA_node_defaults.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/** \file + * \ingroup DNA + */ + +#pragma once + +/* Struct members on own line. */ +/* clang-format off */ + +/* -------------------------------------------------------------------- */ +/** \name bArmature Struct + * \{ */ + +#define _DNA_DEFAULT_bNodeSocket \ + { \ + .category_index = -1, \ + } + +/** \} */ + +/* clang-format on */ diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 8a7f5d45d09..6d35020ac45 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -168,6 +168,10 @@ typedef struct bNodeSocket { /** Custom data for inputs, only UI writes in this. */ bNodeStack ns DNA_DEPRECATED; + /* UI category index of the socket. */ + int category_index; + int _pad2; + bNodeSocketRuntimeHandle *runtime; #ifdef __cplusplus @@ -531,6 +535,12 @@ typedef struct bNodeLink { #define NTREE_CHUNKSIZE_512 512 #define NTREE_CHUNKSIZE_1024 1024 +typedef struct bNodeSocketCategory { + char *name; + int flag; + int _pad; +} bNodeSocketCategory; + /* the basis for a Node tree, all links and nodes reside internal here */ /* only re-usable node trees are in the library though, * materials and textures allocate own tree struct */ @@ -594,6 +604,11 @@ typedef struct bNodeTree { /** Image representing what the node group does. */ struct PreviewImage *preview; + /* UI categories for sockets */ + struct bNodeSocketCategory *socket_categories_array; + int socket_categories_num; + int active_socket_category; + bNodeTreeRuntimeHandle *runtime; #ifdef __cplusplus @@ -657,6 +672,9 @@ typedef struct bNodeTree { /** Inputs and outputs of the entire node group. */ blender::Span interface_inputs() const; blender::Span interface_outputs() const; + + blender::Span socket_categories() const; + blender::MutableSpan socket_categories_for_write(); #endif } bNodeTree; diff --git a/source/blender/makesdna/intern/dna_defaults.c b/source/blender/makesdna/intern/dna_defaults.c index d76b30e9506..6b96e753f58 100644 --- a/source/blender/makesdna/intern/dna_defaults.c +++ b/source/blender/makesdna/intern/dna_defaults.c @@ -126,6 +126,7 @@ #include "DNA_meta_defaults.h" #include "DNA_modifier_defaults.h" #include "DNA_movieclip_defaults.h" +#include "DNA_node_defaults.h" #include "DNA_object_defaults.h" #include "DNA_particle_defaults.h" #include "DNA_pointcloud_defaults.h" diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 34f79a80103..b64dcf97763 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3164,6 +3164,57 @@ static IDProperty **rna_NodeSocketInterface_idprops(PointerRNA *ptr) return &sock->prop; } +static PointerRNA rna_NodeSocketInterface_category_get(PointerRNA *ptr) +{ + bNodeSocket *socket = (bNodeSocket *)ptr->data; + bNodeTree *ntree = (bNodeTree *)ptr->owner_id; + const int index = socket->category_index; + + bNodeSocketCategory *category = NULL; + if (index >= 0 && index < ntree->socket_categories_num) { + category = &ntree->socket_categories_array[index]; + } + + PointerRNA r_ptr; + RNA_pointer_create(&ntree->id, &RNA_NodeSocketCategory, category, &r_ptr); + return r_ptr; +} + +static void rna_NodeSocketInterface_category_set(PointerRNA *ptr, + PointerRNA value, + struct ReportList *reports) +{ + bNodeSocket *socket = (bNodeSocket *)ptr->data; + bNodeTree *ntree = (bNodeTree *)ptr->owner_id; + bNodeSocketCategory *category = (bNodeSocketCategory *)value.data; + + const size_t index = category - ntree->socket_categories_array; + if (index < 0 || index >= ntree->socket_categories_num) { + BKE_report(reports, RPT_ERROR, "Category is not in the node tree interface"); + return; + } + + ntreeSetSocketInterfaceCategory(ntree, socket, category); +} + +static bool rna_NodeSocketInterface_category_poll(PointerRNA *ptr, PointerRNA value) +{ + bNodeSocket *socket = (bNodeSocket *)ptr->data; + bNodeTree *ntree = (bNodeTree *)ptr->owner_id; + bNodeSocketCategory *category = (bNodeSocketCategory *)value.data; + + if (category == NULL) { + return true; + } + + const int index = category - ntree->socket_categories_array; + if (index < 0 || index >= ntree->socket_categories_num) { + return false; + } + + return true; +} + static void rna_NodeSocketInterface_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->owner_id; @@ -3283,6 +3334,96 @@ static void rna_NodeSocketStandard_value_and_relation_update(struct bContext *C, DEG_relations_tag_update(bmain); } +/* ******** Node Socket Categories ******** */ + +static void rna_NodeSocketCategory_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) +{ + bNodeTree *ntree = (bNodeTree *)ptr->owner_id; + BKE_ntree_update_tag_interface(ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); +} + +static bNodeSocketCategory *rna_NodeTree_socket_categories_new(bNodeTree *ntree, + Main *bmain, + ReportList *reports, + const char *name) +{ + bNodeSocketCategory *category = ntreeAddSocketCategory(ntree, name, 0); + + if (category == NULL) { + BKE_report(reports, RPT_ERROR, "Unable to create socket category"); + } + else { + BKE_ntree_update_tag_interface(ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); + WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); + } + + return category; +} + +static void rna_NodeTree_socket_categories_remove(bNodeTree *ntree, + Main *bmain, + bNodeSocketCategory *category) +{ + ntreeRemoveSocketCategory(ntree, category); + + BKE_ntree_update_tag_interface(ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); + WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); +} + +static void rna_NodeTree_socket_categories_clear(bNodeTree *ntree, Main *bmain) +{ + ntreeClearSocketCategories(ntree); + + BKE_ntree_update_tag_interface(ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); + WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); +} + +static void rna_NodeTree_socket_categories_move(bNodeTree *ntree, + Main *bmain, + int from_index, + int to_index) +{ + if (from_index < 0 || from_index >= ntree->socket_categories_num || to_index < 0 || + to_index >= ntree->socket_categories_num) + { + return; + } + + ntreeMoveSocketCategory(ntree, &ntree->socket_categories_array[from_index], to_index); + + BKE_ntree_update_tag_interface(ntree); + ED_node_tree_propagate_change(NULL, bmain, ntree); + WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); +} + +static PointerRNA rna_NodeTree_active_socket_category_get(PointerRNA *ptr) +{ + bNodeTree *ntree = (bNodeTree *)ptr->data; + bNodeSocketCategory *category = NULL; + if (ntree->active_socket_category >= 0 && + ntree->active_socket_category < ntree->socket_categories_num) + { + category = &ntree->socket_categories_array[ntree->active_socket_category]; + } + + PointerRNA r_ptr; + RNA_pointer_create(ptr->owner_id, &RNA_NodeSocketCategory, category, &r_ptr); + return r_ptr; +} + +static void rna_NodeTree_active_socket_category_set(PointerRNA *ptr, + PointerRNA value, + struct ReportList *UNUSED(reports)) +{ + bNodeSocketCategory *category = (bNodeSocketCategory *)value.data; + bNodeTree *ntree = (bNodeTree *)ptr->data; + ntree->active_socket_category = category - ntree->socket_categories_array; +} + /* ******** Node Types ******** */ static void rna_NodeInternalSocketTemplate_name_get(PointerRNA *ptr, char *value) @@ -11610,6 +11751,18 @@ static void rna_def_node_socket_interface(BlenderRNA *brna) "Don't show the input value in the geometry nodes modifier interface"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + prop = RNA_def_property(srna, "category", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_funcs(prop, + "rna_NodeSocketInterface_category_get", + "rna_NodeSocketInterface_category_set", + NULL, + "rna_NodeSocketInterface_category_poll"); + RNA_def_property_struct_type(prop, "NodeSocketCategory"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text( + prop, "Socket Category", "Category to group sockets together in the UI"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + prop = RNA_def_property(srna, "attribute_domain", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_enum_attribute_domain_items); RNA_def_property_ui_text( @@ -12878,6 +13031,23 @@ static void rna_def_node_link(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Is Hidden", "Link is hidden due to invisible sockets"); } +static void rna_def_node_socket_category(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "NodeSocketCategory", NULL); + RNA_def_struct_ui_text(srna, "NodeSocketCategory", "Group of sockets in node tree interface"); + RNA_def_struct_sdna(srna, "bNodeSocketCategory"); + RNA_def_struct_ui_icon(srna, ICON_NODE); + + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "name"); + RNA_def_property_ui_text(prop, "Name", "Name of the socket category"); + RNA_def_struct_name_property(srna, prop); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketCategory_update"); +} + static void rna_def_nodetree_nodes_api(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; @@ -13017,6 +13187,66 @@ static void rna_def_node_tree_sockets_api(BlenderRNA *brna, PropertyRNA *cprop, RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); } +static void rna_def_node_tree_socket_categories_api(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + PropertyRNA *prop; + PropertyRNA *parm; + FunctionRNA *func; + + RNA_def_property_srna(cprop, "NodeSocketCategories"); + srna = RNA_def_struct(brna, "NodeSocketCategories", NULL); + RNA_def_struct_sdna(srna, "bNodeTree"); + RNA_def_struct_ui_text( + srna, "Node Tree Socket Categories", "Collection of socket categories in a node tree"); + + prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); + RNA_def_property_int_sdna(prop, NULL, "active_socket_category"); + RNA_def_property_ui_text(prop, "Active Index", "Index of the active category"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, NC_NODE, NULL); + + prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); + RNA_def_property_struct_type(prop, "NodeSocketCategory"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_pointer_funcs(prop, + "rna_NodeTree_active_socket_category_get", + "rna_NodeTree_active_socket_category_set", + NULL, + NULL); + RNA_def_property_ui_text(prop, "Active", "Active category"); + RNA_def_property_update(prop, NC_NODE, NULL); + + func = RNA_def_function(srna, "new", "rna_NodeTree_socket_categories_new"); + RNA_def_function_ui_description(func, "Add a new socket category to the tree"); + RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS); + parm = RNA_def_string(func, "name", NULL, MAX_NAME, "Name", ""); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + /* return value */ + parm = RNA_def_pointer(func, "category", "NodeSocketCategory", "", "New category"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove", "rna_NodeTree_socket_categories_remove"); + RNA_def_function_ui_description(func, "Remove a socket category from the tree"); + RNA_def_function_flag(func, FUNC_USE_MAIN); + parm = RNA_def_pointer(func, "category", "NodeSocketCategory", "", "The category to remove"); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + + func = RNA_def_function(srna, "clear", "rna_NodeTree_socket_categories_clear"); + RNA_def_function_ui_description(func, "Remove all categories from the tree"); + RNA_def_function_flag(func, FUNC_USE_MAIN); + + func = RNA_def_function(srna, "move", "rna_NodeTree_socket_categories_move"); + RNA_def_function_ui_description(func, "Move a socket category to another position"); + RNA_def_function_flag(func, FUNC_USE_MAIN); + parm = RNA_def_int( + func, "from_index", -1, 0, INT_MAX, "From Index", "Index of the category to move", 0, 10000); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_int( + func, "to_index", -1, 0, INT_MAX, "To Index", "Target index for the category", 0, 10000); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); +} + static void rna_def_nodetree(BlenderRNA *brna) { StructRNA *srna; @@ -13119,6 +13349,14 @@ static void rna_def_nodetree(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_NODE, NULL); + prop = RNA_def_property(srna, "socket_categories", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "socket_categories_array", "socket_categories_num"); + RNA_def_property_struct_type(prop, "NodeSocketCategory"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text( + prop, "Socket Categories", "Socket categories for structuring the node tree interface"); + rna_def_node_tree_socket_categories_api(brna, prop); + /* exposed as a function for runtime interface type properties */ func = RNA_def_function(srna, "interface_update", "rna_NodeTree_interface_update"); RNA_def_function_ui_description(func, "Updated node group interface"); @@ -13389,6 +13627,7 @@ void RNA_def_nodetree(BlenderRNA *brna) rna_def_simulation_state_item(brna); rna_def_function_node(brna); + rna_def_node_socket_category(brna); rna_def_nodetree(brna); rna_def_node_socket_standard_types(brna); -- 2.30.2 From 5c8233edb3124aecefe44e16a20125efe19f9487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Tue, 6 Jun 2023 11:25:18 +0200 Subject: [PATCH 02/22] Removed unnecessary range check of unsigned integer variable. --- source/blender/makesrna/intern/rna_nodetree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index b64dcf97763..b427d9cbe06 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3189,7 +3189,7 @@ static void rna_NodeSocketInterface_category_set(PointerRNA *ptr, bNodeSocketCategory *category = (bNodeSocketCategory *)value.data; const size_t index = category - ntree->socket_categories_array; - if (index < 0 || index >= ntree->socket_categories_num) { + if (index >= ntree->socket_categories_num) { BKE_report(reports, RPT_ERROR, "Category is not in the node tree interface"); return; } -- 2.30.2 From 5bf853f3aa0edd68bc5c5fff6c94a8cbbe6bd16d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Tue, 6 Jun 2023 12:18:54 +0200 Subject: [PATCH 03/22] Removed unused variable. --- source/blender/makesrna/intern/rna_nodetree.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index b427d9cbe06..c6531074eed 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3199,7 +3199,6 @@ static void rna_NodeSocketInterface_category_set(PointerRNA *ptr, static bool rna_NodeSocketInterface_category_poll(PointerRNA *ptr, PointerRNA value) { - bNodeSocket *socket = (bNodeSocket *)ptr->data; bNodeTree *ntree = (bNodeTree *)ptr->owner_id; bNodeSocketCategory *category = (bNodeSocketCategory *)value.data; -- 2.30.2 From c7ab5dc0681e6d7794cb3209110c1ae9c921cffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Tue, 6 Jun 2023 17:14:08 +0200 Subject: [PATCH 04/22] Added a `category_id` identifier for stable Panel<->category relations. Instead of just an index, we now use the category_id to specify the category of a socket as well as associating a panel with a category. This has two consequences: 1. No need to remap indices after adding/removing/moving a category. Flip side is that finding the category of a socket now requires a linear search. In future this could be more efficient using a map, but that is a separate task. 2. Now the panel open/closed state bits are associated with a stable identifier, so panels will retain their state when moving. --- source/blender/blenkernel/BKE_node.h | 16 ++-- source/blender/blenkernel/intern/node.cc | 84 ++++++++----------- .../blenloader/intern/versioning_400.cc | 6 +- .../blender/editors/space_node/node_edit.cc | 2 +- source/blender/makesdna/DNA_node_defaults.h | 2 +- source/blender/makesdna/DNA_node_types.h | 8 +- source/blender/makesrna/intern/rna_nodetree.c | 18 ++-- 7 files changed, 65 insertions(+), 71 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 8b408847164..d67997f186e 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -566,18 +566,24 @@ void ntreeSetSocketInterfaceCategory(bNodeTree *ntree, /** \name Node Tree Socket Categories * \{ */ +/** + * Find a socket category by its unique ID. + * \param id: Unique ID of the category within the node tree. + */ +bNodeSocketCategory *ntreeFindSocketCategoryByID(bNodeTree *ntree, int id); + /** * Add a new socket category to the node tree. - * \param name Name of the new category. - * \param name Flags of the new category. + * \param name: Name of the new category. + * \param flag: Flags of the new category. */ bNodeSocketCategory *ntreeAddSocketCategory(bNodeTree *ntree, const char *name, int flag); /** * Insert a new socket category in the node tree. - * \param name Name of the new category. - * \param name Flags of the new category. - * \param index Index at which to insert the category. + * \param name: Name of the new category. + * \param flag: Flags of the new category. + * \param index: Index at which to insert the category. */ bNodeSocketCategory *ntreeInsertSocketCategory(bNodeTree *ntree, const char *name, diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index c1447f88216..0235c2e1654 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -3658,7 +3658,7 @@ static bNodeSocket *make_socket_interface(bNodeTree *ntree, STRNCPY(sock->name, name); sock->storage = nullptr; sock->flag |= SOCK_COLLAPSED; - sock->category_index = -1; + sock->category_id = -1; return sock; } @@ -3667,7 +3667,7 @@ static int node_socket_category_cmp(const void *a, const void *b) { const bNodeSocket *sock_a = static_cast(a); const bNodeSocket *sock_b = static_cast(b); - return (sock_a->category_index > sock_b->category_index) ? 1 : 0; + return (sock_a->category_id > sock_b->category_id) ? 1 : 0; } bNodeSocket *ntreeFindSocketInterface(bNodeTree *ntree, @@ -3687,8 +3687,32 @@ bNodeSocket *ntreeFindSocketInterface(bNodeTree *ntree, void ntreeEnsureSocketCategoryOrder(bNodeTree *ntree) { + /* XXX Hack: store category index in category_id temporarily for sorting. */ + LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->inputs) { + const bNodeSocketCategory *category = ntreeFindSocketCategoryByID(ntree, iosock->category_id); + iosock->category_id = category == nullptr ? -1 : + (int)(category - ntree->socket_categories_array); + } + LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->outputs) { + const bNodeSocketCategory *category = ntreeFindSocketCategoryByID(ntree, iosock->category_id); + iosock->category_id = category == nullptr ? -1 : + (int)(category - ntree->socket_categories_array); + } BLI_listbase_sort(&ntree->inputs, blender::bke::node_socket_category_cmp); BLI_listbase_sort(&ntree->outputs, blender::bke::node_socket_category_cmp); + /* Restore category_id. */ + LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->inputs) { + if (iosock->category_id >= 0) { + const bNodeSocketCategory &category = ntree->socket_categories()[iosock->category_id]; + iosock->category_id = category.identifier; + } + } + LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->outputs) { + if (iosock->category_id >= 0) { + const bNodeSocketCategory &category = ntree->socket_categories()[iosock->category_id]; + iosock->category_id = category.identifier; + } + } } bNodeSocket *ntreeAddSocketInterface(bNodeTree *ntree, @@ -3715,12 +3739,11 @@ void ntreeSetSocketInterfaceCategory(bNodeTree *ntree, bNodeSocketCategory *category) { if (category == NULL) { - socket->category_index = -1; + socket->category_id = -1; return; } - socket->category_index = category - ntree->socket_categories_array; - BLI_assert(ntree->socket_categories().index_range().contains(socket->category_index)); + socket->category_id = category->identifier; ntreeEnsureSocketCategoryOrder(ntree); @@ -3805,25 +3828,16 @@ void ntreeRemoveSocketInterface(bNodeTree *ntree, bNodeSocket *sock) BKE_ntree_update_tag_interface(ntree); } -namespace blender::bke { - -/* Fix socket category indices after changes. */ -static void remap_socket_categories(bNodeTree &ntree, std::function index_fn) +bNodeSocketCategory *ntreeFindSocketCategoryByID(bNodeTree *ntree, int id) { - LISTBASE_FOREACH (bNodeSocket *, socket, &ntree.inputs) { - socket->category_index = index_fn(socket->category_index); - BLI_assert(socket->category_index == -1 || - ntree.socket_categories().index_range().contains(socket->category_index)); - } - LISTBASE_FOREACH (bNodeSocket *, socket, &ntree.outputs) { - socket->category_index = index_fn(socket->category_index); - BLI_assert(socket->category_index == -1 || - ntree.socket_categories().index_range().contains(socket->category_index)); + for (bNodeSocketCategory &category : ntree->socket_categories_for_write()) { + if (category.identifier == id) { + return &category; + } } + return nullptr; } -} // namespace blender::bke - bNodeSocketCategory *ntreeAddSocketCategory(bNodeTree *ntree, const char *name, int flag) { bNodeSocketCategory *old_categories_array = ntree->socket_categories_array; @@ -3837,11 +3851,10 @@ bNodeSocketCategory *ntreeAddSocketCategory(bNodeTree *ntree, const char *name, new_categories[i] = old_categories[i]; } bNodeSocketCategory &new_category = new_categories[new_categories.size() - 1]; - new_category = {BLI_strdup(name), flag}; + new_category = {BLI_strdup(name), flag, ntree->next_socket_category_identifier++}; MEM_SAFE_FREE(old_categories_array); - /* No need to remap socket categories, in this case old indices stay the same. */ /* No need to sort sockets, nothing is using the new category yet */ return &new_category; @@ -3870,14 +3883,10 @@ bNodeSocketCategory *ntreeInsertSocketCategory(bNodeTree *ntree, new_categories[i + 1] = old_categories[i]; } bNodeSocketCategory &new_category = new_categories[index]; - new_category = {BLI_strdup(name), flag}; + new_category = {BLI_strdup(name), flag, ntree->next_socket_category_identifier++}; MEM_SAFE_FREE(old_categories_array); - blender::bke::remap_socket_categories(*ntree, [index](const int old_category_index) { - return old_category_index < index ? old_category_index : old_category_index + 1; - }); - /* No need to sort sockets, nothing is using the new category yet */ return &new_category; @@ -3906,11 +3915,6 @@ void ntreeRemoveSocketCategory(bNodeTree *ntree, bNodeSocketCategory *category) MEM_SAFE_FREE(old_categories_array); - blender::bke::remap_socket_categories(*ntree, [index](const int old_category_index) { - return old_category_index < index ? old_category_index : - (old_category_index > index ? old_category_index - 1 : -1); - }); - ntreeEnsureSocketCategoryOrder(ntree); } @@ -3920,8 +3924,6 @@ void ntreeClearSocketCategories(bNodeTree *ntree) ntree->socket_categories_array = nullptr; ntree->socket_categories_num = 0; - blender::bke::remap_socket_categories(*ntree, [](const int /*old_index*/) { return -1; }); - /* No need to sort sockets, only null category exists, relative order remains unchanged. */ } @@ -3943,13 +3945,6 @@ void ntreeMoveSocketCategory(bNodeTree *ntree, bNodeSocketCategory *category, in categories[i] = categories[i + 1]; } categories[new_index] = tmp; - - blender::bke::remap_socket_categories( - *ntree, [old_index, new_index](const int old_category_index) { - return old_category_index < old_index || old_category_index > new_index ? - old_category_index : - (old_category_index == old_index ? new_index : old_category_index - 1); - }); } else /* old_index > new_index */ { const bNodeSocketCategory tmp = categories[old_index]; @@ -3957,13 +3952,6 @@ void ntreeMoveSocketCategory(bNodeTree *ntree, bNodeSocketCategory *category, in categories[i] = categories[i - 1]; } categories[new_index] = tmp; - - blender::bke::remap_socket_categories( - *ntree, [old_index, new_index](const int old_category_index) { - return old_category_index < new_index || old_category_index > old_index ? - old_category_index : - (old_category_index == old_index ? new_index : old_category_index + 1); - }); } ntreeEnsureSocketCategoryOrder(ntree); diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index 5d474b76202..8cc7dae2604 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -138,13 +138,13 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) { /* Keep this block, even when empty. */ - if (!DNA_struct_elem_find(fd->filesdna, "bNodeSocket", "int", "category_index")) { + if (!DNA_struct_elem_find(fd->filesdna, "bNodeSocket", "int", "category_id")) { FOREACH_NODETREE_BEGIN (bmain, ntree, id) { LISTBASE_FOREACH (bNodeSocket *, socket, &ntree->inputs) { - socket->category_index = -1; + socket->category_id = -1; } LISTBASE_FOREACH (bNodeSocket *, socket, &ntree->outputs) { - socket->category_index = -1; + socket->category_id = -1; } } FOREACH_NODETREE_END; diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index cfd0effa141..245c60991c1 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -2192,7 +2192,7 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op) /* XXX this only works for actual sockets, not interface templates! */ // nodeSocketCopyValue(sock, &ntree_ptr, active_sock, &ntree_ptr); /* Inherit socket category from the active socket interface. */ - sock->category_index = active_sock->category_index; + sock->category_id = active_sock->category_id; } else { /* XXX TODO: define default socket type for a tree! */ diff --git a/source/blender/makesdna/DNA_node_defaults.h b/source/blender/makesdna/DNA_node_defaults.h index 1b528a2e5b5..126062aba0a 100644 --- a/source/blender/makesdna/DNA_node_defaults.h +++ b/source/blender/makesdna/DNA_node_defaults.h @@ -15,7 +15,7 @@ #define _DNA_DEFAULT_bNodeSocket \ { \ - .category_index = -1, \ + .category_id = -1, \ } /** \} */ diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 6d35020ac45..f59960ecafe 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -168,8 +168,8 @@ typedef struct bNodeSocket { /** Custom data for inputs, only UI writes in this. */ bNodeStack ns DNA_DEPRECATED; - /* UI category index of the socket. */ - int category_index; + /* ID of the UI category of the socket. */ + int category_id; int _pad2; bNodeSocketRuntimeHandle *runtime; @@ -538,7 +538,7 @@ typedef struct bNodeLink { typedef struct bNodeSocketCategory { char *name; int flag; - int _pad; + int identifier; } bNodeSocketCategory; /* the basis for a Node tree, all links and nodes reside internal here */ @@ -608,6 +608,8 @@ typedef struct bNodeTree { struct bNodeSocketCategory *socket_categories_array; int socket_categories_num; int active_socket_category; + int next_socket_category_identifier; + char _pad2[4]; bNodeTreeRuntimeHandle *runtime; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index c6531074eed..4086d4caaf1 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3168,12 +3168,8 @@ static PointerRNA rna_NodeSocketInterface_category_get(PointerRNA *ptr) { bNodeSocket *socket = (bNodeSocket *)ptr->data; bNodeTree *ntree = (bNodeTree *)ptr->owner_id; - const int index = socket->category_index; - bNodeSocketCategory *category = NULL; - if (index >= 0 && index < ntree->socket_categories_num) { - category = &ntree->socket_categories_array[index]; - } + bNodeSocketCategory *category = ntreeFindSocketCategoryByID(ntree, socket->category_id); PointerRNA r_ptr; RNA_pointer_create(&ntree->id, &RNA_NodeSocketCategory, category, &r_ptr); @@ -3188,10 +3184,12 @@ static void rna_NodeSocketInterface_category_set(PointerRNA *ptr, bNodeTree *ntree = (bNodeTree *)ptr->owner_id; bNodeSocketCategory *category = (bNodeSocketCategory *)value.data; - const size_t index = category - ntree->socket_categories_array; - if (index >= ntree->socket_categories_num) { - BKE_report(reports, RPT_ERROR, "Category is not in the node tree interface"); - return; + if (category != NULL) { + const int64_t index = category - ntree->socket_categories_array; + if (index < 0 || index >= ntree->socket_categories_num) { + BKE_report(reports, RPT_ERROR, "Category is not in the node tree interface"); + return; + } } ntreeSetSocketInterfaceCategory(ntree, socket, category); @@ -3206,7 +3204,7 @@ static bool rna_NodeSocketInterface_category_poll(PointerRNA *ptr, PointerRNA va return true; } - const int index = category - ntree->socket_categories_array; + const int64_t index = category - ntree->socket_categories_array; if (index < 0 || index >= ntree->socket_categories_num) { return false; } -- 2.30.2 From d7aa257d2d2689e3eeb9e7b92dcf1a0b26aa420b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Tue, 6 Jun 2023 18:32:55 +0200 Subject: [PATCH 05/22] Cleanup: comment style fixes. --- scripts/startup/bl_operators/node.py | 2 +- source/blender/blenkernel/BKE_node.h | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/scripts/startup/bl_operators/node.py b/scripts/startup/bl_operators/node.py index de5990c7806..c184c8e8864 100644 --- a/scripts/startup/bl_operators/node.py +++ b/scripts/startup/bl_operators/node.py @@ -269,7 +269,7 @@ class NODE_OT_socket_category_add(NodeSocketCategoryOperator, Operator): tree = snode.edit_tree categories = tree.socket_categories - # Remember index to move the item + # Remember index to move the item. dst_index = min(categories.active_index + 1, len(categories)) categories.new("Category") categories.move(len(categories) - 1, dst_index) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index d67997f186e..72931a75cf8 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -542,10 +542,7 @@ void ntreeBlendWrite(struct BlendWriter *writer, struct bNodeTree *ntree); /** \name Node Tree Interface * \{ */ -/** - * Run this after relevant changes to categories - * to ensure sockets remain sorted by category. - */ +/** Run this after relevant changes to categories to ensure sockets remain sorted by category. */ void ntreeEnsureSocketCategoryOrder(bNodeTree *ntree); void ntreeRemoveSocketInterface(bNodeTree *ntree, bNodeSocket *sock); @@ -598,7 +595,7 @@ void ntreeClearSocketCategories(bNodeTree *ntree); /** * Move a socket category up or down in the node tree. - * \param index Index to which to move the category. + * \param index: Index to which to move the category. */ void ntreeMoveSocketCategory(bNodeTree *ntree, bNodeSocketCategory *category, int new_index); -- 2.30.2 From df7713dcfcaaf1a1c6b4ca7c623cab2ef347ad80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Tue, 6 Jun 2023 18:36:26 +0200 Subject: [PATCH 06/22] Use __func__ for MEM_malloc strings. --- source/blender/blenkernel/intern/node.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 0235c2e1654..19e468ab2d4 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -3843,7 +3843,7 @@ bNodeSocketCategory *ntreeAddSocketCategory(bNodeTree *ntree, const char *name, bNodeSocketCategory *old_categories_array = ntree->socket_categories_array; const Span old_categories = ntree->socket_categories(); ntree->socket_categories_array = MEM_cnew_array( - ntree->socket_categories_num + 1, "socket categories"); + ntree->socket_categories_num + 1, __func__); ++ntree->socket_categories_num; const MutableSpan new_categories = ntree->socket_categories_for_write(); @@ -3872,7 +3872,7 @@ bNodeSocketCategory *ntreeInsertSocketCategory(bNodeTree *ntree, bNodeSocketCategory *old_categories_array = ntree->socket_categories_array; const Span old_categories = ntree->socket_categories(); ntree->socket_categories_array = MEM_cnew_array( - ntree->socket_categories_num + 1, "socket categories"); + ntree->socket_categories_num + 1, __func__); ++ntree->socket_categories_num; const MutableSpan new_categories = ntree->socket_categories_for_write(); @@ -3902,7 +3902,7 @@ void ntreeRemoveSocketCategory(bNodeTree *ntree, bNodeSocketCategory *category) bNodeSocketCategory *old_categories_array = ntree->socket_categories_array; const Span old_categories = ntree->socket_categories(); ntree->socket_categories_array = MEM_cnew_array( - ntree->socket_categories_num - 1, "socket categories"); + ntree->socket_categories_num - 1, __func__); --ntree->socket_categories_num; const MutableSpan new_categories = ntree->socket_categories_for_write(); -- 2.30.2 From 530678fc8de3e2822be8ba3372c9ca7163149699 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Wed, 7 Jun 2023 11:07:43 +0200 Subject: [PATCH 07/22] Use std::copy for category add/remove/move methods. --- source/blender/blenkernel/intern/node.cc | 46 ++++++++++++------------ 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 19e468ab2d4..f2363f8d615 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -3847,9 +3847,7 @@ bNodeSocketCategory *ntreeAddSocketCategory(bNodeTree *ntree, const char *name, ++ntree->socket_categories_num; const MutableSpan new_categories = ntree->socket_categories_for_write(); - for (const int i : new_categories.index_range().drop_back(1)) { - new_categories[i] = old_categories[i]; - } + std::copy(old_categories.begin(), old_categories.end(), new_categories.data()); bNodeSocketCategory &new_category = new_categories[new_categories.size() - 1]; new_category = {BLI_strdup(name), flag, ntree->next_socket_category_identifier++}; @@ -3876,12 +3874,12 @@ bNodeSocketCategory *ntreeInsertSocketCategory(bNodeTree *ntree, ++ntree->socket_categories_num; const MutableSpan new_categories = ntree->socket_categories_for_write(); - for (const int i : new_categories.index_range().take_front(index)) { - new_categories[i] = old_categories[i]; - } - for (const int i : new_categories.index_range().drop_front(index)) { - new_categories[i + 1] = old_categories[i]; - } + Span old_categories_front = old_categories.take_front(index); + Span old_categories_back = old_categories.drop_front(index); + std::copy(old_categories_front.begin(), old_categories_front.end(), new_categories.data()); + std::copy(old_categories_back.begin(), + old_categories_back.end(), + new_categories.drop_front(index + 1).data()); bNodeSocketCategory &new_category = new_categories[index]; new_category = {BLI_strdup(name), flag, ntree->next_socket_category_identifier++}; @@ -3906,12 +3904,12 @@ void ntreeRemoveSocketCategory(bNodeTree *ntree, bNodeSocketCategory *category) --ntree->socket_categories_num; const MutableSpan new_categories = ntree->socket_categories_for_write(); - for (const int i : new_categories.index_range().take_front(index)) { - new_categories[i] = old_categories[i]; - } - for (const int i : new_categories.index_range().drop_front(index)) { - new_categories[i] = old_categories[i + 1]; - } + Span old_categories_front = old_categories.take_front(index); + Span old_categories_back = old_categories.drop_front(index + 1); + std::copy(old_categories_front.begin(), old_categories_front.end(), new_categories.data()); + std::copy(old_categories_back.begin(), + old_categories_back.end(), + new_categories.drop_front(index).data()); MEM_SAFE_FREE(old_categories_array); @@ -3929,28 +3927,30 @@ void ntreeClearSocketCategories(bNodeTree *ntree) void ntreeMoveSocketCategory(bNodeTree *ntree, bNodeSocketCategory *category, int new_index) { - const int old_index = category - ntree->socket_categories_array; if (!ntree->socket_categories().contains_ptr(category)) { return; } const MutableSpan categories = ntree->socket_categories_for_write(); - + const int old_index = category - ntree->socket_categories_array; if (old_index == new_index) { return; } else if (old_index < new_index) { + const Span moved_categories = categories.slice(old_index + 1, + new_index - old_index); const bNodeSocketCategory tmp = categories[old_index]; - for (int i = old_index; i < new_index; ++i) { - categories[i] = categories[i + 1]; - } + std::copy( + moved_categories.begin(), moved_categories.end(), categories.drop_front(old_index).data()); categories[new_index] = tmp; } else /* old_index > new_index */ { + const Span moved_categories = categories.slice(new_index, + old_index - new_index); const bNodeSocketCategory tmp = categories[old_index]; - for (int i = old_index; i > new_index; --i) { - categories[i] = categories[i - 1]; - } + std::copy_backward(moved_categories.begin(), + moved_categories.end(), + categories.drop_front(old_index + 1).data()); categories[new_index] = tmp; } -- 2.30.2 From 4f0b237e5044d4ecf039b04ec170c5103ca65943 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Wed, 7 Jun 2023 11:10:58 +0200 Subject: [PATCH 08/22] Cleanup: remove some newlines. --- source/blender/makesrna/intern/rna_nodetree.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 4086d4caaf1..34321520b3e 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3168,7 +3168,6 @@ static PointerRNA rna_NodeSocketInterface_category_get(PointerRNA *ptr) { bNodeSocket *socket = (bNodeSocket *)ptr->data; bNodeTree *ntree = (bNodeTree *)ptr->owner_id; - bNodeSocketCategory *category = ntreeFindSocketCategoryByID(ntree, socket->category_id); PointerRNA r_ptr; @@ -3199,7 +3198,6 @@ static bool rna_NodeSocketInterface_category_poll(PointerRNA *ptr, PointerRNA va { bNodeTree *ntree = (bNodeTree *)ptr->owner_id; bNodeSocketCategory *category = (bNodeSocketCategory *)value.data; - if (category == NULL) { return true; } -- 2.30.2 From f1724234410aa4ea33301018981a4b21ed9fd405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Thu, 8 Jun 2023 11:17:26 +0200 Subject: [PATCH 09/22] Cleanup: Rename "category" to "panel". --- scripts/startup/bl_operators/node.py | 64 +++--- scripts/startup/bl_ui/space_node.py | 30 +-- source/blender/blenkernel/BKE_node.h | 53 ++--- source/blender/blenkernel/BKE_node_runtime.hh | 10 +- source/blender/blenkernel/intern/node.cc | 216 ++++++++---------- .../blenloader/intern/versioning_400.cc | 6 +- source/blender/editors/space_node/drawnode.cc | 2 +- .../blender/editors/space_node/node_edit.cc | 6 +- source/blender/makesdna/DNA_node_defaults.h | 2 +- source/blender/makesdna/DNA_node_types.h | 23 +- source/blender/makesrna/intern/rna_nodetree.c | 160 ++++++------- 11 files changed, 276 insertions(+), 296 deletions(-) diff --git a/scripts/startup/bl_operators/node.py b/scripts/startup/bl_operators/node.py index f65768e2d3d..06156e69006 100644 --- a/scripts/startup/bl_operators/node.py +++ b/scripts/startup/bl_operators/node.py @@ -244,7 +244,7 @@ class NODE_OT_tree_path_parent(Operator): return {'FINISHED'} -class NodeSocketCategoryOperator(): +class NodeSocketPanelOperator(): @classmethod def poll(cls, context): snode = context.space_data @@ -258,48 +258,48 @@ class NodeSocketCategoryOperator(): return True -class NODE_OT_socket_category_add(NodeSocketCategoryOperator, Operator): - '''Add a new socket category to the tree''' - bl_idname = "node.function_parameter_add" - bl_label = "Add Socket Category" +class NODE_OT_socket_panel_add(NodeSocketPanelOperator, Operator): + '''Add a new socket panel to the tree''' + bl_idname = "node.socket_panel_add" + bl_label = "Add Socket Panel" bl_options = {'REGISTER', 'UNDO'} def execute(self, context): snode = context.space_data tree = snode.edit_tree - categories = tree.socket_categories + panels = tree.socket_panels # Remember index to move the item. - dst_index = min(categories.active_index + 1, len(categories)) - categories.new("Category") - categories.move(len(categories) - 1, dst_index) - categories.active_index = dst_index + dst_index = min(panels.active_index + 1, len(panels)) + panels.new("Panel") + panels.move(len(panels) - 1, dst_index) + panels.active_index = dst_index return {'FINISHED'} -class NODE_OT_socket_category_remove(NodeSocketCategoryOperator, Operator): - '''Remove a socket category from the tree''' - bl_idname = "node.function_parameter_remove" - bl_label = "Remove Socket Category" +class NODE_OT_socket_panel_remove(NodeSocketPanelOperator, Operator): + '''Remove a socket panel from the tree''' + bl_idname = "node.socket_panel_remove" + bl_label = "Remove Socket Panel" bl_options = {'REGISTER', 'UNDO'} def execute(self, context): snode = context.space_data tree = snode.edit_tree - categories = tree.socket_categories + panels = tree.socket_panels - if categories.active: - categories.remove(categories.active) - categories.active_index = min(categories.active_index, len(categories) - 1) + if panels.active: + panels.remove(panels.active) + panels.active_index = min(panels.active_index, len(panels) - 1) return {'FINISHED'} -class NODE_OT_socket_category_move(NodeSocketCategoryOperator, Operator): - '''Move a socket category to another position''' - bl_idname = "node.function_parameter_move" - bl_label = "Move Socket Category" +class NODE_OT_socket_panel_move(NodeSocketPanelOperator, Operator): + '''Move a socket panel to another position''' + bl_idname = "node.socket_panel_move" + bl_label = "Move Socket Panel" bl_options = {'REGISTER', 'UNDO'} direction: EnumProperty( @@ -311,14 +311,14 @@ class NODE_OT_socket_category_move(NodeSocketCategoryOperator, Operator): def execute(self, context): snode = context.space_data tree = snode.edit_tree - categories = tree.socket_categories + panels = tree.socket_panels - if self.direction == 'UP' and categories.active_index > 0: - categories.move(categories.active_index, categories.active_index - 1) - categories.active_index -= 1 - elif self.direction == 'DOWN' and categories.active_index < len(categories) - 1: - categories.move(categories.active_index, categories.active_index + 1) - categories.active_index += 1 + if self.direction == 'UP' and panels.active_index > 0: + panels.move(panels.active_index, panels.active_index - 1) + panels.active_index -= 1 + elif self.direction == 'DOWN' and panels.active_index < len(panels) - 1: + panels.move(panels.active_index, panels.active_index + 1) + panels.active_index += 1 return {'FINISHED'} @@ -329,8 +329,8 @@ classes = ( NODE_OT_add_node, NODE_OT_add_simulation_zone, NODE_OT_collapse_hide_unused_toggle, - NODE_OT_socket_category_add, - NODE_OT_socket_category_remove, - NODE_OT_socket_category_move, + NODE_OT_socket_panel_add, + NODE_OT_socket_panel_remove, + NODE_OT_socket_panel_move, NODE_OT_tree_path_parent, ) diff --git a/scripts/startup/bl_ui/space_node.py b/scripts/startup/bl_ui/space_node.py index 242936b811f..4ac936e5714 100644 --- a/scripts/startup/bl_ui/space_node.py +++ b/scripts/startup/bl_ui/space_node.py @@ -954,17 +954,17 @@ class NODE_PT_node_tree_interface_outputs(NodeTreeInterfacePanel): self.draw_socket_list(context, "OUT", "outputs", "active_output") -class NODE_UL_socket_categories(bpy.types.UIList): +class NODE_UL_socket_panels(bpy.types.UIList): def draw_item(self, context, layout, _data, item, icon, _active_data, _active_propname, _index): row = layout.row(align=True) row.prop(item, "name", text="", emboss=False, icon_value=icon) -class NODE_PT_socket_categories(Panel): +class NODE_PT_socket_panels(Panel): bl_space_type = 'NODE_EDITOR' bl_region_type = 'UI' bl_category = "Group" - bl_label = "Socket Categories" + bl_label = "Socket Panels" @classmethod def poll(cls, context): @@ -986,30 +986,30 @@ class NODE_PT_socket_categories(Panel): split = layout.row() split.template_list( - "NODE_UL_socket_categories", + "NODE_UL_socket_panels", "", tree, - "socket_categories", - tree.socket_categories, + "socket_panels", + tree.socket_panels, "active_index") ops_col = split.column() add_remove_col = ops_col.column(align=True) - add_remove_col.operator("node.function_parameter_add", icon='ADD', text="") - add_remove_col.operator("node.function_parameter_remove", icon='REMOVE', text="") + add_remove_col.operator("node.socket_panel_add", icon='ADD', text="") + add_remove_col.operator("node.socket_panel_remove", icon='REMOVE', text="") ops_col.separator() up_down_col = ops_col.column(align=True) - props = up_down_col.operator("node.function_parameter_move", icon='TRIA_UP', text="") + props = up_down_col.operator("node.socket_panel_move", icon='TRIA_UP', text="") props.direction = 'UP' - props = up_down_col.operator("node.function_parameter_move", icon='TRIA_DOWN', text="") + props = up_down_col.operator("node.socket_panel_move", icon='TRIA_DOWN', text="") props.direction = 'DOWN' - active_category = tree.socket_categories.active - if active_category is not None: - layout.prop(active_category, "name") + active_panel = tree.socket_panels.active + if active_panel is not None: + layout.prop(active_panel, "name") class NODE_UL_simulation_zone_items(bpy.types.UIList): @@ -1155,8 +1155,8 @@ classes = ( NODE_UL_interface_sockets, NODE_PT_node_tree_interface_inputs, NODE_PT_node_tree_interface_outputs, - NODE_UL_socket_categories, - NODE_PT_socket_categories, + NODE_UL_socket_panels, + NODE_PT_socket_panels, NODE_UL_simulation_zone_items, NODE_PT_simulation_zone_items, diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 72931a75cf8..4fddbe6268d 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -542,8 +542,8 @@ void ntreeBlendWrite(struct BlendWriter *writer, struct bNodeTree *ntree); /** \name Node Tree Interface * \{ */ -/** Run this after relevant changes to categories to ensure sockets remain sorted by category. */ -void ntreeEnsureSocketCategoryOrder(bNodeTree *ntree); +/** Run this after relevant changes to panels to ensure sockets remain sorted by panel. */ +void ntreeEnsureSocketInterfacePanelOrder(bNodeTree *ntree); void ntreeRemoveSocketInterface(bNodeTree *ntree, bNodeSocket *sock); @@ -552,52 +552,47 @@ struct bNodeSocket *ntreeAddSocketInterface(struct bNodeTree *ntree, const char *idname, const char *name); -/** Set the category of the interface socket. */ -void ntreeSetSocketInterfaceCategory(bNodeTree *ntree, - bNodeSocket *sock, - bNodeSocketCategory *category); +/** Set the panel of the interface socket. */ +void ntreeSetSocketInterfacePanel(bNodeTree *ntree, bNodeSocket *sock, bNodeSocketPanel *panel); /** \} */ /* -------------------------------------------------------------------- */ -/** \name Node Tree Socket Categories +/** \name Node Tree Socket Panels * \{ */ /** - * Find a socket category by its unique ID. - * \param id: Unique ID of the category within the node tree. + * Find a socket panel by its unique ID. + * \param id: Unique ID of the panel within the node tree. */ -bNodeSocketCategory *ntreeFindSocketCategoryByID(bNodeTree *ntree, int id); +bNodeSocketPanel *ntreeFindSocketPanelByID(bNodeTree *ntree, int id); /** - * Add a new socket category to the node tree. - * \param name: Name of the new category. - * \param flag: Flags of the new category. + * Add a new socket panel to the node tree. + * \param name: Name of the new panel. + * \param flag: Flags of the new panel. */ -bNodeSocketCategory *ntreeAddSocketCategory(bNodeTree *ntree, const char *name, int flag); +bNodeSocketPanel *ntreeAddSocketPanel(bNodeTree *ntree, const char *name, int flag); /** - * Insert a new socket category in the node tree. - * \param name: Name of the new category. - * \param flag: Flags of the new category. - * \param index: Index at which to insert the category. + * Insert a new socket panel in the node tree. + * \param name: Name of the new panel. + * \param flag: Flags of the new panel. + * \param index: Index at which to insert the panel. */ -bNodeSocketCategory *ntreeInsertSocketCategory(bNodeTree *ntree, - const char *name, - int flag, - int index); +bNodeSocketPanel *ntreeInsertSocketPanel(bNodeTree *ntree, const char *name, int flag, int index); -/** Remove a socket category from the node tree. */ -void ntreeRemoveSocketCategory(bNodeTree *ntree, bNodeSocketCategory *category); +/** Remove a socket panel from the node tree. */ +void ntreeRemoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel); -/** Remove all socket categories from the node tree. */ -void ntreeClearSocketCategories(bNodeTree *ntree); +/** Remove all socket panels from the node tree. */ +void ntreeClearSocketPanels(bNodeTree *ntree); /** - * Move a socket category up or down in the node tree. - * \param index: Index to which to move the category. + * Move a socket panel up or down in the node tree. + * \param index: Index to which to move the panel. */ -void ntreeMoveSocketCategory(bNodeTree *ntree, bNodeSocketCategory *category, int new_index); +void ntreeMoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel, int new_index); /** \} */ diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index 8969f91ba91..4ff9387be76 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -516,18 +516,16 @@ inline blender::Span bNodeTree::root_frames() const return this->runtime->root_frames; } -inline blender::Span bNodeTree::socket_categories() const +inline blender::Span bNodeTree::socket_panels() const { - return blender::Span(socket_categories_array, socket_categories_num); + return blender::Span(socket_panels_array, socket_panels_num); } -inline blender::MutableSpan bNodeTree::socket_categories_for_write() +inline blender::MutableSpan bNodeTree::socket_panels_for_write() { - return blender::MutableSpan(socket_categories_array, socket_categories_num); + return blender::MutableSpan(socket_panels_array, socket_panels_num); } -/** \} */ - /* -------------------------------------------------------------------- */ /** \name #bNode Inline Methods * \{ */ diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 5b3e1faab86..0b021a587a1 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -646,9 +646,9 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree) } BLO_write_struct_array( - writer, bNodeSocketCategory, ntree->socket_categories_num, ntree->socket_categories_array); - for (const bNodeSocketCategory &category : ntree->socket_categories()) { - BLO_write_string(writer, category.name); + writer, bNodeSocketPanel, ntree->socket_panels_num, ntree->socket_panels_array); + for (const bNodeSocketPanel &panel : ntree->socket_panels()) { + BLO_write_string(writer, panel.name); } BKE_previewimg_blend_write(writer, ntree->preview); @@ -871,9 +871,9 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree) BLO_read_data_address(reader, &link->tosock); } - BLO_read_data_address(reader, &ntree->socket_categories_array); - for (bNodeSocketCategory &category : ntree->socket_categories_for_write()) { - BLO_read_data_address(reader, &category.name); + BLO_read_data_address(reader, &ntree->socket_panels_array); + for (bNodeSocketPanel &panel : ntree->socket_panels_for_write()) { + BLO_read_data_address(reader, &panel.name); } /* TODO: should be dealt by new generic cache handling of IDs... */ @@ -3661,16 +3661,16 @@ static bNodeSocket *make_socket_interface(bNodeTree *ntree, STRNCPY(sock->name, name); sock->storage = nullptr; sock->flag |= SOCK_COLLAPSED; - sock->category_id = -1; + sock->panel_id = -1; return sock; } -static int node_socket_category_cmp(const void *a, const void *b) +static int node_socket_panel_cmp(const void *a, const void *b) { const bNodeSocket *sock_a = static_cast(a); const bNodeSocket *sock_b = static_cast(b); - return (sock_a->category_id > sock_b->category_id) ? 1 : 0; + return (sock_a->panel_id > sock_b->panel_id) ? 1 : 0; } bNodeSocket *ntreeFindSocketInterface(bNodeTree *ntree, @@ -3688,32 +3688,30 @@ bNodeSocket *ntreeFindSocketInterface(bNodeTree *ntree, } // namespace blender::bke -void ntreeEnsureSocketCategoryOrder(bNodeTree *ntree) +void ntreeEnsureSocketInterfacePanelOrder(bNodeTree *ntree) { - /* XXX Hack: store category index in category_id temporarily for sorting. */ + /* XXX Hack: store panel index in panel_id temporarily for sorting. */ LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->inputs) { - const bNodeSocketCategory *category = ntreeFindSocketCategoryByID(ntree, iosock->category_id); - iosock->category_id = category == nullptr ? -1 : - (int)(category - ntree->socket_categories_array); + const bNodeSocketPanel *panel = ntreeFindSocketPanelByID(ntree, iosock->panel_id); + iosock->panel_id = panel == nullptr ? -1 : (int)(panel - ntree->socket_panels_array); } LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->outputs) { - const bNodeSocketCategory *category = ntreeFindSocketCategoryByID(ntree, iosock->category_id); - iosock->category_id = category == nullptr ? -1 : - (int)(category - ntree->socket_categories_array); + const bNodeSocketPanel *panel = ntreeFindSocketPanelByID(ntree, iosock->panel_id); + iosock->panel_id = panel == nullptr ? -1 : (int)(panel - ntree->socket_panels_array); } - BLI_listbase_sort(&ntree->inputs, blender::bke::node_socket_category_cmp); - BLI_listbase_sort(&ntree->outputs, blender::bke::node_socket_category_cmp); - /* Restore category_id. */ + BLI_listbase_sort(&ntree->inputs, blender::bke::node_socket_panel_cmp); + BLI_listbase_sort(&ntree->outputs, blender::bke::node_socket_panel_cmp); + /* Restore panel_id. */ LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->inputs) { - if (iosock->category_id >= 0) { - const bNodeSocketCategory &category = ntree->socket_categories()[iosock->category_id]; - iosock->category_id = category.identifier; + if (iosock->panel_id >= 0) { + const bNodeSocketPanel &panel = ntree->socket_panels()[iosock->panel_id]; + iosock->panel_id = panel.identifier; } } LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->outputs) { - if (iosock->category_id >= 0) { - const bNodeSocketCategory &category = ntree->socket_categories()[iosock->category_id]; - iosock->category_id = category.identifier; + if (iosock->panel_id >= 0) { + const bNodeSocketPanel &panel = ntree->socket_panels()[iosock->panel_id]; + iosock->panel_id = panel.identifier; } } } @@ -3731,24 +3729,22 @@ bNodeSocket *ntreeAddSocketInterface(bNodeTree *ntree, BLI_addtail(&ntree->outputs, iosock); } - ntreeEnsureSocketCategoryOrder(ntree); + ntreeEnsureSocketInterfacePanelOrder(ntree); BKE_ntree_update_tag_interface(ntree); return iosock; } -void ntreeSetSocketInterfaceCategory(bNodeTree *ntree, - bNodeSocket *socket, - bNodeSocketCategory *category) +void ntreeSetSocketInterfacePanel(bNodeTree *ntree, bNodeSocket *socket, bNodeSocketPanel *panel) { - if (category == NULL) { - socket->category_id = -1; + if (panel == NULL) { + socket->panel_id = -1; return; } - socket->category_id = category->identifier; + socket->panel_id = panel->identifier; - ntreeEnsureSocketCategoryOrder(ntree); + ntreeEnsureSocketInterfacePanelOrder(ntree); BKE_ntree_update_tag_interface(ntree); } @@ -3769,7 +3765,7 @@ bNodeSocket *ntreeInsertSocketInterface(bNodeTree *ntree, BLI_insertlinkbefore(&ntree->outputs, next_sock, iosock); } - ntreeEnsureSocketCategoryOrder(ntree); + ntreeEnsureSocketInterfacePanelOrder(ntree); BKE_ntree_update_tag_interface(ntree); return iosock; @@ -3826,138 +3822,128 @@ void ntreeRemoveSocketInterface(bNodeTree *ntree, bNodeSocket *sock) blender::bke::node_socket_interface_free(ntree, sock, true); MEM_freeN(sock); - /* No need to resort by category, removing doesn't change anything. */ + /* No need to resort by panel, removing doesn't change anything. */ BKE_ntree_update_tag_interface(ntree); } -bNodeSocketCategory *ntreeFindSocketCategoryByID(bNodeTree *ntree, int id) +bNodeSocketPanel *ntreeFindSocketPanelByID(bNodeTree *ntree, int id) { - for (bNodeSocketCategory &category : ntree->socket_categories_for_write()) { - if (category.identifier == id) { - return &category; + for (bNodeSocketPanel &panel : ntree->socket_panels_for_write()) { + if (panel.identifier == id) { + return &panel; } } return nullptr; } -bNodeSocketCategory *ntreeAddSocketCategory(bNodeTree *ntree, const char *name, int flag) +bNodeSocketPanel *ntreeAddSocketPanel(bNodeTree *ntree, const char *name, int flag) { - bNodeSocketCategory *old_categories_array = ntree->socket_categories_array; - const Span old_categories = ntree->socket_categories(); - ntree->socket_categories_array = MEM_cnew_array( - ntree->socket_categories_num + 1, __func__); - ++ntree->socket_categories_num; - const MutableSpan new_categories = ntree->socket_categories_for_write(); + bNodeSocketPanel *old_panels_array = ntree->socket_panels_array; + const Span old_panels = ntree->socket_panels(); + ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num + 1, + __func__); + ++ntree->socket_panels_num; + const MutableSpan new_panels = ntree->socket_panels_for_write(); - std::copy(old_categories.begin(), old_categories.end(), new_categories.data()); - bNodeSocketCategory &new_category = new_categories[new_categories.size() - 1]; - new_category = {BLI_strdup(name), flag, ntree->next_socket_category_identifier++}; + std::copy(old_panels.begin(), old_panels.end(), new_panels.data()); + bNodeSocketPanel &new_panel = new_panels[new_panels.size() - 1]; + new_panel = {BLI_strdup(name), flag, ntree->next_socket_panel_identifier++}; - MEM_SAFE_FREE(old_categories_array); + MEM_SAFE_FREE(old_panels_array); - /* No need to sort sockets, nothing is using the new category yet */ + /* No need to sort sockets, nothing is using the new panel yet */ - return &new_category; + return &new_panel; } -bNodeSocketCategory *ntreeInsertSocketCategory(bNodeTree *ntree, - const char *name, - int flag, - int index) +bNodeSocketPanel *ntreeInsertSocketPanel(bNodeTree *ntree, const char *name, int flag, int index) { - if (!blender::IndexRange(ntree->socket_categories().size() + 1).contains(index)) { + if (!blender::IndexRange(ntree->socket_panels().size() + 1).contains(index)) { return nullptr; } - bNodeSocketCategory *old_categories_array = ntree->socket_categories_array; - const Span old_categories = ntree->socket_categories(); - ntree->socket_categories_array = MEM_cnew_array( - ntree->socket_categories_num + 1, __func__); - ++ntree->socket_categories_num; - const MutableSpan new_categories = ntree->socket_categories_for_write(); + bNodeSocketPanel *old_panels_array = ntree->socket_panels_array; + const Span old_panels = ntree->socket_panels(); + ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num + 1, + __func__); + ++ntree->socket_panels_num; + const MutableSpan new_panels = ntree->socket_panels_for_write(); - Span old_categories_front = old_categories.take_front(index); - Span old_categories_back = old_categories.drop_front(index); - std::copy(old_categories_front.begin(), old_categories_front.end(), new_categories.data()); - std::copy(old_categories_back.begin(), - old_categories_back.end(), - new_categories.drop_front(index + 1).data()); - bNodeSocketCategory &new_category = new_categories[index]; - new_category = {BLI_strdup(name), flag, ntree->next_socket_category_identifier++}; + Span old_panels_front = old_panels.take_front(index); + Span old_panels_back = old_panels.drop_front(index); + std::copy(old_panels_front.begin(), old_panels_front.end(), new_panels.data()); + std::copy( + old_panels_back.begin(), old_panels_back.end(), new_panels.drop_front(index + 1).data()); + bNodeSocketPanel &new_panel = new_panels[index]; + new_panel = {BLI_strdup(name), flag, ntree->next_socket_panel_identifier++}; - MEM_SAFE_FREE(old_categories_array); + MEM_SAFE_FREE(old_panels_array); - /* No need to sort sockets, nothing is using the new category yet */ + /* No need to sort sockets, nothing is using the new panel yet */ - return &new_category; + return &new_panel; } -void ntreeRemoveSocketCategory(bNodeTree *ntree, bNodeSocketCategory *category) +void ntreeRemoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel) { - const int index = category - ntree->socket_categories_array; - if (!ntree->socket_categories().contains_ptr(category)) { + const int index = panel - ntree->socket_panels_array; + if (!ntree->socket_panels().contains_ptr(panel)) { return; } - bNodeSocketCategory *old_categories_array = ntree->socket_categories_array; - const Span old_categories = ntree->socket_categories(); - ntree->socket_categories_array = MEM_cnew_array( - ntree->socket_categories_num - 1, __func__); - --ntree->socket_categories_num; - const MutableSpan new_categories = ntree->socket_categories_for_write(); + bNodeSocketPanel *old_panels_array = ntree->socket_panels_array; + const Span old_panels = ntree->socket_panels(); + ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num - 1, + __func__); + --ntree->socket_panels_num; + const MutableSpan new_panels = ntree->socket_panels_for_write(); - Span old_categories_front = old_categories.take_front(index); - Span old_categories_back = old_categories.drop_front(index + 1); - std::copy(old_categories_front.begin(), old_categories_front.end(), new_categories.data()); - std::copy(old_categories_back.begin(), - old_categories_back.end(), - new_categories.drop_front(index).data()); + Span old_panels_front = old_panels.take_front(index); + Span old_panels_back = old_panels.drop_front(index + 1); + std::copy(old_panels_front.begin(), old_panels_front.end(), new_panels.data()); + std::copy(old_panels_back.begin(), old_panels_back.end(), new_panels.drop_front(index).data()); - MEM_SAFE_FREE(old_categories_array); + MEM_SAFE_FREE(old_panels_array); - ntreeEnsureSocketCategoryOrder(ntree); + ntreeEnsureSocketInterfacePanelOrder(ntree); } -void ntreeClearSocketCategories(bNodeTree *ntree) +void ntreeClearSocketPanels(bNodeTree *ntree) { - MEM_SAFE_FREE(ntree->socket_categories_array); - ntree->socket_categories_array = nullptr; - ntree->socket_categories_num = 0; + MEM_SAFE_FREE(ntree->socket_panels_array); + ntree->socket_panels_array = nullptr; + ntree->socket_panels_num = 0; - /* No need to sort sockets, only null category exists, relative order remains unchanged. */ + /* No need to sort sockets, only null panel exists, relative order remains unchanged. */ } -void ntreeMoveSocketCategory(bNodeTree *ntree, bNodeSocketCategory *category, int new_index) +void ntreeMoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel, int new_index) { - if (!ntree->socket_categories().contains_ptr(category)) { + if (!ntree->socket_panels().contains_ptr(panel)) { return; } - const MutableSpan categories = ntree->socket_categories_for_write(); - const int old_index = category - ntree->socket_categories_array; + const MutableSpan panels = ntree->socket_panels_for_write(); + const int old_index = panel - ntree->socket_panels_array; if (old_index == new_index) { return; } else if (old_index < new_index) { - const Span moved_categories = categories.slice(old_index + 1, - new_index - old_index); - const bNodeSocketCategory tmp = categories[old_index]; - std::copy( - moved_categories.begin(), moved_categories.end(), categories.drop_front(old_index).data()); - categories[new_index] = tmp; + const Span moved_panels = panels.slice(old_index + 1, new_index - old_index); + const bNodeSocketPanel tmp = panels[old_index]; + std::copy(moved_panels.begin(), moved_panels.end(), panels.drop_front(old_index).data()); + panels[new_index] = tmp; } else /* old_index > new_index */ { - const Span moved_categories = categories.slice(new_index, - old_index - new_index); - const bNodeSocketCategory tmp = categories[old_index]; - std::copy_backward(moved_categories.begin(), - moved_categories.end(), - categories.drop_front(old_index + 1).data()); - categories[new_index] = tmp; + const Span moved_panels = panels.slice(new_index, old_index - new_index); + const bNodeSocketPanel tmp = panels[old_index]; + std::copy_backward( + moved_panels.begin(), moved_panels.end(), panels.drop_front(old_index + 1).data()); + panels[new_index] = tmp; } - ntreeEnsureSocketCategoryOrder(ntree); + ntreeEnsureSocketInterfacePanelOrder(ntree); } namespace blender::bke { diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index ff4bef9cbe4..ee883dc20af 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -150,13 +150,13 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) { /* Keep this block, even when empty. */ - if (!DNA_struct_elem_find(fd->filesdna, "bNodeSocket", "int", "category_id")) { + if (!DNA_struct_elem_find(fd->filesdna, "bNodeSocket", "int", "panel_id")) { FOREACH_NODETREE_BEGIN (bmain, ntree, id) { LISTBASE_FOREACH (bNodeSocket *, socket, &ntree->inputs) { - socket->category_id = -1; + socket->panel_id = -1; } LISTBASE_FOREACH (bNodeSocket *, socket, &ntree->outputs) { - socket->category_id = -1; + socket->panel_id = -1; } } FOREACH_NODETREE_END; diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index 77f96fa3bcc..25f38afd8ca 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -1481,7 +1481,7 @@ static void std_node_socket_interface_draw(bContext * /*C*/, uiLayout *layout, P uiItemR(col, ptr, "hide_in_modifier", DEFAULT_FLAGS, nullptr, 0); } - uiItemPointerR(col, ptr, "category", &tree_ptr, "socket_categories", nullptr, 0); + uiItemPointerR(col, ptr, "panel", &tree_ptr, "socket_panels", nullptr, 0); } static void node_socket_virtual_draw_color(bContext * /*C*/, diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index 245c60991c1..82a790c6693 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -2191,8 +2191,8 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op) ntree, in_out, active_sock->idname, active_sock->next, active_sock->name); /* XXX this only works for actual sockets, not interface templates! */ // nodeSocketCopyValue(sock, &ntree_ptr, active_sock, &ntree_ptr); - /* Inherit socket category from the active socket interface. */ - sock->category_id = active_sock->category_id; + /* Inherit socket panel from the active socket interface. */ + sock->panel_id = active_sock->panel_id; } else { /* XXX TODO: define default socket type for a tree! */ @@ -2584,7 +2584,7 @@ static int ntree_socket_move_exec(bContext *C, wmOperator *op) } } - ntreeEnsureSocketCategoryOrder(ntree); + ntreeEnsureSocketInterfacePanelOrder(ntree); BKE_ntree_update_tag_interface(ntree); ED_node_tree_propagate_change(C, CTX_data_main(C), ntree); diff --git a/source/blender/makesdna/DNA_node_defaults.h b/source/blender/makesdna/DNA_node_defaults.h index 126062aba0a..f63c0398f94 100644 --- a/source/blender/makesdna/DNA_node_defaults.h +++ b/source/blender/makesdna/DNA_node_defaults.h @@ -15,7 +15,7 @@ #define _DNA_DEFAULT_bNodeSocket \ { \ - .category_id = -1, \ + .panel_id = -1, \ } /** \} */ diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index b99e4639149..90150ab16c2 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -168,8 +168,8 @@ typedef struct bNodeSocket { /** Custom data for inputs, only UI writes in this. */ bNodeStack ns DNA_DEPRECATED; - /* ID of the UI category of the socket. */ - int category_id; + /* ID of the UI panel of the socket. */ + int panel_id; int _pad2; bNodeSocketRuntimeHandle *runtime; @@ -535,11 +535,12 @@ typedef struct bNodeLink { #define NTREE_CHUNKSIZE_512 512 #define NTREE_CHUNKSIZE_1024 1024 -typedef struct bNodeSocketCategory { +/** Panel in node tree for grouping sockets. */ +typedef struct bNodeSocketPanel { char *name; int flag; int identifier; -} bNodeSocketCategory; +} bNodeSocketPanel; /* the basis for a Node tree, all links and nodes reside internal here */ /* only re-usable node trees are in the library though, @@ -604,11 +605,11 @@ typedef struct bNodeTree { /** Image representing what the node group does. */ struct PreviewImage *preview; - /* UI categories for sockets */ - struct bNodeSocketCategory *socket_categories_array; - int socket_categories_num; - int active_socket_category; - int next_socket_category_identifier; + /* UI panels for sockets */ + struct bNodeSocketPanel *socket_panels_array; + int socket_panels_num; + int active_socket_panel; + int next_socket_panel_identifier; char _pad2[4]; bNodeTreeRuntimeHandle *runtime; @@ -675,8 +676,8 @@ typedef struct bNodeTree { blender::Span interface_inputs() const; blender::Span interface_outputs() const; - blender::Span socket_categories() const; - blender::MutableSpan socket_categories_for_write(); + blender::Span socket_panels() const; + blender::MutableSpan socket_panels_for_write(); #endif } bNodeTree; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 34321520b3e..5cd0227cc8b 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3164,46 +3164,46 @@ static IDProperty **rna_NodeSocketInterface_idprops(PointerRNA *ptr) return &sock->prop; } -static PointerRNA rna_NodeSocketInterface_category_get(PointerRNA *ptr) +static PointerRNA rna_NodeSocketInterface_panel_get(PointerRNA *ptr) { bNodeSocket *socket = (bNodeSocket *)ptr->data; bNodeTree *ntree = (bNodeTree *)ptr->owner_id; - bNodeSocketCategory *category = ntreeFindSocketCategoryByID(ntree, socket->category_id); + bNodeSocketPanel *panel = ntreeFindSocketPanelByID(ntree, socket->panel_id); PointerRNA r_ptr; - RNA_pointer_create(&ntree->id, &RNA_NodeSocketCategory, category, &r_ptr); + RNA_pointer_create(&ntree->id, &RNA_NodeSocketPanel, panel, &r_ptr); return r_ptr; } -static void rna_NodeSocketInterface_category_set(PointerRNA *ptr, +static void rna_NodeSocketInterface_panel_set(PointerRNA *ptr, PointerRNA value, struct ReportList *reports) { bNodeSocket *socket = (bNodeSocket *)ptr->data; bNodeTree *ntree = (bNodeTree *)ptr->owner_id; - bNodeSocketCategory *category = (bNodeSocketCategory *)value.data; + bNodeSocketPanel *panel = (bNodeSocketPanel *)value.data; - if (category != NULL) { - const int64_t index = category - ntree->socket_categories_array; - if (index < 0 || index >= ntree->socket_categories_num) { - BKE_report(reports, RPT_ERROR, "Category is not in the node tree interface"); + if (panel != NULL) { + const int64_t index = panel - ntree->socket_panels_array; + if (index < 0 || index >= ntree->socket_panels_num) { + BKE_report(reports, RPT_ERROR, "Panel is not in the node tree interface"); return; } } - ntreeSetSocketInterfaceCategory(ntree, socket, category); + ntreeSetSocketInterfacePanel(ntree, socket, panel); } -static bool rna_NodeSocketInterface_category_poll(PointerRNA *ptr, PointerRNA value) +static bool rna_NodeSocketInterface_panel_poll(PointerRNA *ptr, PointerRNA value) { bNodeTree *ntree = (bNodeTree *)ptr->owner_id; - bNodeSocketCategory *category = (bNodeSocketCategory *)value.data; - if (category == NULL) { + bNodeSocketPanel *panel = (bNodeSocketPanel *)value.data; + if (panel == NULL) { return true; } - const int64_t index = category - ntree->socket_categories_array; - if (index < 0 || index >= ntree->socket_categories_num) { + const int64_t index = panel - ntree->socket_panels_array; + if (index < 0 || index >= ntree->socket_panels_num) { return false; } @@ -3329,24 +3329,24 @@ static void rna_NodeSocketStandard_value_and_relation_update(struct bContext *C, DEG_relations_tag_update(bmain); } -/* ******** Node Socket Categories ******** */ +/* ******** Node Socket Panels ******** */ -static void rna_NodeSocketCategory_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) +static void rna_NodeSocketPanel_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->owner_id; BKE_ntree_update_tag_interface(ntree); ED_node_tree_propagate_change(NULL, bmain, ntree); } -static bNodeSocketCategory *rna_NodeTree_socket_categories_new(bNodeTree *ntree, +static bNodeSocketPanel *rna_NodeTree_socket_panels_new(bNodeTree *ntree, Main *bmain, ReportList *reports, const char *name) { - bNodeSocketCategory *category = ntreeAddSocketCategory(ntree, name, 0); + bNodeSocketPanel *panel = ntreeAddSocketPanel(ntree, name, 0); - if (category == NULL) { - BKE_report(reports, RPT_ERROR, "Unable to create socket category"); + if (panel == NULL) { + BKE_report(reports, RPT_ERROR, "Unable to create socket panel"); } else { BKE_ntree_update_tag_interface(ntree); @@ -3354,69 +3354,69 @@ static bNodeSocketCategory *rna_NodeTree_socket_categories_new(bNodeTree *ntree, WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } - return category; + return panel; } -static void rna_NodeTree_socket_categories_remove(bNodeTree *ntree, +static void rna_NodeTree_socket_panels_remove(bNodeTree *ntree, Main *bmain, - bNodeSocketCategory *category) + bNodeSocketPanel *panel) { - ntreeRemoveSocketCategory(ntree, category); + ntreeRemoveSocketPanel(ntree, panel); BKE_ntree_update_tag_interface(ntree); ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } -static void rna_NodeTree_socket_categories_clear(bNodeTree *ntree, Main *bmain) +static void rna_NodeTree_socket_panels_clear(bNodeTree *ntree, Main *bmain) { - ntreeClearSocketCategories(ntree); + ntreeClearSocketPanels(ntree); BKE_ntree_update_tag_interface(ntree); ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } -static void rna_NodeTree_socket_categories_move(bNodeTree *ntree, +static void rna_NodeTree_socket_panels_move(bNodeTree *ntree, Main *bmain, int from_index, int to_index) { - if (from_index < 0 || from_index >= ntree->socket_categories_num || to_index < 0 || - to_index >= ntree->socket_categories_num) + if (from_index < 0 || from_index >= ntree->socket_panels_num || to_index < 0 || + to_index >= ntree->socket_panels_num) { return; } - ntreeMoveSocketCategory(ntree, &ntree->socket_categories_array[from_index], to_index); + ntreeMoveSocketPanel(ntree, &ntree->socket_panels_array[from_index], to_index); BKE_ntree_update_tag_interface(ntree); ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } -static PointerRNA rna_NodeTree_active_socket_category_get(PointerRNA *ptr) +static PointerRNA rna_NodeTree_active_socket_panel_get(PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->data; - bNodeSocketCategory *category = NULL; - if (ntree->active_socket_category >= 0 && - ntree->active_socket_category < ntree->socket_categories_num) + bNodeSocketPanel *panel = NULL; + if (ntree->active_socket_panel >= 0 && + ntree->active_socket_panel < ntree->socket_panels_num) { - category = &ntree->socket_categories_array[ntree->active_socket_category]; + panel = &ntree->socket_panels_array[ntree->active_socket_panel]; } PointerRNA r_ptr; - RNA_pointer_create(ptr->owner_id, &RNA_NodeSocketCategory, category, &r_ptr); + RNA_pointer_create(ptr->owner_id, &RNA_NodeSocketPanel, panel, &r_ptr); return r_ptr; } -static void rna_NodeTree_active_socket_category_set(PointerRNA *ptr, +static void rna_NodeTree_active_socket_panel_set(PointerRNA *ptr, PointerRNA value, struct ReportList *UNUSED(reports)) { - bNodeSocketCategory *category = (bNodeSocketCategory *)value.data; + bNodeSocketPanel *panel = (bNodeSocketPanel *)value.data; bNodeTree *ntree = (bNodeTree *)ptr->data; - ntree->active_socket_category = category - ntree->socket_categories_array; + ntree->active_socket_panel = panel - ntree->socket_panels_array; } /* ******** Node Types ******** */ @@ -11746,16 +11746,16 @@ static void rna_def_node_socket_interface(BlenderRNA *brna) "Don't show the input value in the geometry nodes modifier interface"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); - prop = RNA_def_property(srna, "category", PROP_POINTER, PROP_NONE); + prop = RNA_def_property(srna, "panel", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_funcs(prop, - "rna_NodeSocketInterface_category_get", - "rna_NodeSocketInterface_category_set", + "rna_NodeSocketInterface_panel_get", + "rna_NodeSocketInterface_panel_set", NULL, - "rna_NodeSocketInterface_category_poll"); - RNA_def_property_struct_type(prop, "NodeSocketCategory"); + "rna_NodeSocketInterface_panel_poll"); + RNA_def_property_struct_type(prop, "NodeSocketPanel"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text( - prop, "Socket Category", "Category to group sockets together in the UI"); + prop, "Socket Panel", "Panel to group sockets together in the UI"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); prop = RNA_def_property(srna, "attribute_domain", PROP_ENUM, PROP_NONE); @@ -13026,21 +13026,21 @@ static void rna_def_node_link(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Is Hidden", "Link is hidden due to invisible sockets"); } -static void rna_def_node_socket_category(BlenderRNA *brna) +static void rna_def_node_socket_panel(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - srna = RNA_def_struct(brna, "NodeSocketCategory", NULL); - RNA_def_struct_ui_text(srna, "NodeSocketCategory", "Group of sockets in node tree interface"); - RNA_def_struct_sdna(srna, "bNodeSocketCategory"); + srna = RNA_def_struct(brna, "NodeSocketPanel", NULL); + RNA_def_struct_ui_text(srna, "NodeSocketPanel", "Group of sockets in node tree interface"); + RNA_def_struct_sdna(srna, "bNodeSocketPanel"); RNA_def_struct_ui_icon(srna, ICON_NODE); prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "name"); - RNA_def_property_ui_text(prop, "Name", "Name of the socket category"); + RNA_def_property_ui_text(prop, "Name", "Name of the socket panel"); RNA_def_struct_name_property(srna, prop); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketCategory_update"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketPanel_update"); } static void rna_def_nodetree_nodes_api(BlenderRNA *brna, PropertyRNA *cprop) @@ -13182,63 +13182,63 @@ static void rna_def_node_tree_sockets_api(BlenderRNA *brna, PropertyRNA *cprop, RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); } -static void rna_def_node_tree_socket_categories_api(BlenderRNA *brna, PropertyRNA *cprop) +static void rna_def_node_tree_socket_panels_api(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; PropertyRNA *prop; PropertyRNA *parm; FunctionRNA *func; - RNA_def_property_srna(cprop, "NodeSocketCategories"); - srna = RNA_def_struct(brna, "NodeSocketCategories", NULL); + RNA_def_property_srna(cprop, "NodeSocketPanels"); + srna = RNA_def_struct(brna, "NodeSocketPanels", NULL); RNA_def_struct_sdna(srna, "bNodeTree"); RNA_def_struct_ui_text( - srna, "Node Tree Socket Categories", "Collection of socket categories in a node tree"); + srna, "Node Tree Socket Panels", "Collection of socket panels in a node tree"); prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_sdna(prop, NULL, "active_socket_category"); - RNA_def_property_ui_text(prop, "Active Index", "Index of the active category"); + RNA_def_property_int_sdna(prop, NULL, "active_socket_panel"); + RNA_def_property_ui_text(prop, "Active Index", "Index of the active panel"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_NODE, NULL); prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); - RNA_def_property_struct_type(prop, "NodeSocketCategory"); + RNA_def_property_struct_type(prop, "NodeSocketPanel"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_pointer_funcs(prop, - "rna_NodeTree_active_socket_category_get", - "rna_NodeTree_active_socket_category_set", + "rna_NodeTree_active_socket_panel_get", + "rna_NodeTree_active_socket_panel_set", NULL, NULL); - RNA_def_property_ui_text(prop, "Active", "Active category"); + RNA_def_property_ui_text(prop, "Active", "Active panel"); RNA_def_property_update(prop, NC_NODE, NULL); - func = RNA_def_function(srna, "new", "rna_NodeTree_socket_categories_new"); - RNA_def_function_ui_description(func, "Add a new socket category to the tree"); + func = RNA_def_function(srna, "new", "rna_NodeTree_socket_panels_new"); + RNA_def_function_ui_description(func, "Add a new socket panel to the tree"); RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS); parm = RNA_def_string(func, "name", NULL, MAX_NAME, "Name", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); /* return value */ - parm = RNA_def_pointer(func, "category", "NodeSocketCategory", "", "New category"); + parm = RNA_def_pointer(func, "panel", "NodeSocketPanel", "", "New panel"); RNA_def_function_return(func, parm); - func = RNA_def_function(srna, "remove", "rna_NodeTree_socket_categories_remove"); - RNA_def_function_ui_description(func, "Remove a socket category from the tree"); + func = RNA_def_function(srna, "remove", "rna_NodeTree_socket_panels_remove"); + RNA_def_function_ui_description(func, "Remove a socket panel from the tree"); RNA_def_function_flag(func, FUNC_USE_MAIN); - parm = RNA_def_pointer(func, "category", "NodeSocketCategory", "", "The category to remove"); + parm = RNA_def_pointer(func, "panel", "NodeSocketPanel", "", "The panel to remove"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); - func = RNA_def_function(srna, "clear", "rna_NodeTree_socket_categories_clear"); - RNA_def_function_ui_description(func, "Remove all categories from the tree"); + func = RNA_def_function(srna, "clear", "rna_NodeTree_socket_panels_clear"); + RNA_def_function_ui_description(func, "Remove all panels from the tree"); RNA_def_function_flag(func, FUNC_USE_MAIN); - func = RNA_def_function(srna, "move", "rna_NodeTree_socket_categories_move"); - RNA_def_function_ui_description(func, "Move a socket category to another position"); + func = RNA_def_function(srna, "move", "rna_NodeTree_socket_panels_move"); + RNA_def_function_ui_description(func, "Move a socket panel to another position"); RNA_def_function_flag(func, FUNC_USE_MAIN); parm = RNA_def_int( - func, "from_index", -1, 0, INT_MAX, "From Index", "Index of the category to move", 0, 10000); + func, "from_index", -1, 0, INT_MAX, "From Index", "Index of the panel to move", 0, 10000); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); parm = RNA_def_int( - func, "to_index", -1, 0, INT_MAX, "To Index", "Target index for the category", 0, 10000); + func, "to_index", -1, 0, INT_MAX, "To Index", "Target index for the panel", 0, 10000); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); } @@ -13344,13 +13344,13 @@ static void rna_def_nodetree(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_NODE, NULL); - prop = RNA_def_property(srna, "socket_categories", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "socket_categories_array", "socket_categories_num"); - RNA_def_property_struct_type(prop, "NodeSocketCategory"); + prop = RNA_def_property(srna, "socket_panels", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "socket_panels_array", "socket_panels_num"); + RNA_def_property_struct_type(prop, "NodeSocketPanel"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text( - prop, "Socket Categories", "Socket categories for structuring the node tree interface"); - rna_def_node_tree_socket_categories_api(brna, prop); + prop, "Socket Panels", "Socket panels for structuring the node tree interface"); + rna_def_node_tree_socket_panels_api(brna, prop); /* exposed as a function for runtime interface type properties */ func = RNA_def_function(srna, "interface_update", "rna_NodeTree_interface_update"); @@ -13622,7 +13622,7 @@ void RNA_def_nodetree(BlenderRNA *brna) rna_def_simulation_state_item(brna); rna_def_function_node(brna); - rna_def_node_socket_category(brna); + rna_def_node_socket_panel(brna); rna_def_nodetree(brna); rna_def_node_socket_standard_types(brna); -- 2.30.2 From 284a6bd094aa6d533cad341db6f347523ee6374c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Thu, 8 Jun 2023 13:03:45 +0200 Subject: [PATCH 10/22] Switch from arrays to ListBase for the categories in node trees. --- source/blender/blenkernel/BKE_node.h | 5 +- source/blender/blenkernel/BKE_node_runtime.hh | 10 -- source/blender/blenkernel/intern/node.cc | 139 ++++++------------ source/blender/makesdna/DNA_node_types.h | 9 +- source/blender/makesrna/intern/rna_nodetree.c | 31 +--- 5 files changed, 55 insertions(+), 139 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 4fddbe6268d..4f861a74471 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -590,9 +590,10 @@ void ntreeClearSocketPanels(bNodeTree *ntree); /** * Move a socket panel up or down in the node tree. - * \param index: Index to which to move the panel. + * \param from_index: Current index of the poanel to move. + * \param to_index: Index to which to move the panel. */ -void ntreeMoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel, int new_index); +void ntreeMoveSocketPanel(bNodeTree *ntree, int from_index, int to_index); /** \} */ diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index 4ff9387be76..629cf8c0c85 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -516,16 +516,6 @@ inline blender::Span bNodeTree::root_frames() const return this->runtime->root_frames; } -inline blender::Span bNodeTree::socket_panels() const -{ - return blender::Span(socket_panels_array, socket_panels_num); -} - -inline blender::MutableSpan bNodeTree::socket_panels_for_write() -{ - return blender::MutableSpan(socket_panels_array, socket_panels_num); -} - /* -------------------------------------------------------------------- */ /** \name #bNode Inline Methods * \{ */ diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 431eae9ed59..29bbffac049 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -643,10 +643,9 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree) write_node_socket_interface(writer, sock); } - BLO_write_struct_array( - writer, bNodeSocketPanel, ntree->socket_panels_num, ntree->socket_panels_array); - for (const bNodeSocketPanel &panel : ntree->socket_panels()) { - BLO_write_string(writer, panel.name); + LISTBASE_FOREACH (bNodeSocketPanel *, panel, &ntree->socket_panels) { + BLO_write_struct(writer, bNodeSocketPanel, panel); + BLO_write_string(writer, panel->name); } BKE_previewimg_blend_write(writer, ntree->preview); @@ -869,9 +868,9 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree) BLO_read_data_address(reader, &link->tosock); } - BLO_read_data_address(reader, &ntree->socket_panels_array); - for (bNodeSocketPanel &panel : ntree->socket_panels_for_write()) { - BLO_read_data_address(reader, &panel.name); + BLO_read_list(reader, &ntree->socket_panels); + LISTBASE_FOREACH (bNodeSocketPanel *, panel, &ntree->socket_panels) { + BLO_read_data_address(reader, &panel->name); } /* TODO: should be dealt by new generic cache handling of IDs... */ @@ -3682,25 +3681,27 @@ void ntreeEnsureSocketInterfacePanelOrder(bNodeTree *ntree) /* XXX Hack: store panel index in panel_id temporarily for sorting. */ LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->inputs) { const bNodeSocketPanel *panel = ntreeFindSocketPanelByID(ntree, iosock->panel_id); - iosock->panel_id = panel == nullptr ? -1 : (int)(panel - ntree->socket_panels_array); + iosock->panel_id = (panel == nullptr ? -1 : BLI_findindex(&ntree->socket_panels, panel)); } LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->outputs) { const bNodeSocketPanel *panel = ntreeFindSocketPanelByID(ntree, iosock->panel_id); - iosock->panel_id = panel == nullptr ? -1 : (int)(panel - ntree->socket_panels_array); + iosock->panel_id = panel == nullptr ? -1 : BLI_findindex(&ntree->socket_panels, panel); } BLI_listbase_sort(&ntree->inputs, blender::bke::node_socket_panel_cmp); BLI_listbase_sort(&ntree->outputs, blender::bke::node_socket_panel_cmp); /* Restore panel_id. */ LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->inputs) { if (iosock->panel_id >= 0) { - const bNodeSocketPanel &panel = ntree->socket_panels()[iosock->panel_id]; - iosock->panel_id = panel.identifier; + const bNodeSocketPanel *panel = static_cast( + BLI_findlink(&ntree->socket_panels, iosock->panel_id)); + iosock->panel_id = panel->identifier; } } LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->outputs) { if (iosock->panel_id >= 0) { - const bNodeSocketPanel &panel = ntree->socket_panels()[iosock->panel_id]; - iosock->panel_id = panel.identifier; + const bNodeSocketPanel *panel = static_cast( + BLI_findlink(&ntree->socket_panels, iosock->panel_id)); + iosock->panel_id = panel->identifier; } } } @@ -3818,9 +3819,9 @@ void ntreeRemoveSocketInterface(bNodeTree *ntree, bNodeSocket *sock) bNodeSocketPanel *ntreeFindSocketPanelByID(bNodeTree *ntree, int id) { - for (bNodeSocketPanel &panel : ntree->socket_panels_for_write()) { - if (panel.identifier == id) { - return &panel; + LISTBASE_FOREACH (bNodeSocketPanel *, panel, &ntree->socket_panels) { + if (panel->identifier == id) { + return panel; } } return nullptr; @@ -3828,111 +3829,53 @@ bNodeSocketPanel *ntreeFindSocketPanelByID(bNodeTree *ntree, int id) bNodeSocketPanel *ntreeAddSocketPanel(bNodeTree *ntree, const char *name, int flag) { - bNodeSocketPanel *old_panels_array = ntree->socket_panels_array; - const Span old_panels = ntree->socket_panels(); - ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num + 1, - __func__); - ++ntree->socket_panels_num; - const MutableSpan new_panels = ntree->socket_panels_for_write(); - - std::copy(old_panels.begin(), old_panels.end(), new_panels.data()); - bNodeSocketPanel &new_panel = new_panels[new_panels.size() - 1]; - new_panel = {BLI_strdup(name), flag, ntree->next_socket_panel_identifier++}; - - MEM_SAFE_FREE(old_panels_array); + bNodeSocketPanel *new_panel = MEM_cnew(__func__); + new_panel->name = BLI_strdup(name); + new_panel->flag = flag; + new_panel->identifier = ntree->next_socket_panel_identifier++; + BLI_addtail(&ntree->socket_panels, new_panel); /* No need to sort sockets, nothing is using the new panel yet */ - - return &new_panel; + return new_panel; } bNodeSocketPanel *ntreeInsertSocketPanel(bNodeTree *ntree, const char *name, int flag, int index) { - if (!blender::IndexRange(ntree->socket_panels().size() + 1).contains(index)) { - return nullptr; - } - - bNodeSocketPanel *old_panels_array = ntree->socket_panels_array; - const Span old_panels = ntree->socket_panels(); - ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num + 1, - __func__); - ++ntree->socket_panels_num; - const MutableSpan new_panels = ntree->socket_panels_for_write(); - - Span old_panels_front = old_panels.take_front(index); - Span old_panels_back = old_panels.drop_front(index); - std::copy(old_panels_front.begin(), old_panels_front.end(), new_panels.data()); - std::copy( - old_panels_back.begin(), old_panels_back.end(), new_panels.drop_front(index + 1).data()); - bNodeSocketPanel &new_panel = new_panels[index]; - new_panel = {BLI_strdup(name), flag, ntree->next_socket_panel_identifier++}; - - MEM_SAFE_FREE(old_panels_array); + bNodeSocketPanel *new_panel = MEM_cnew(__func__); + new_panel->name = BLI_strdup(name); + new_panel->flag = flag; + new_panel->identifier = ntree->next_socket_panel_identifier++; + bNodeSocketPanel *panel_after = static_cast( + BLI_findlink(&ntree->socket_panels, index)); + BLI_insertlinkbefore(&ntree->socket_panels, panel_after, new_panel); /* No need to sort sockets, nothing is using the new panel yet */ - - return &new_panel; + return new_panel; } void ntreeRemoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel) { - const int index = panel - ntree->socket_panels_array; - if (!ntree->socket_panels().contains_ptr(panel)) { - return; + if (BLI_remlink_safe(&ntree->socket_panels, panel)) { + MEM_SAFE_FREE(panel->name); + MEM_delete(panel); } - - bNodeSocketPanel *old_panels_array = ntree->socket_panels_array; - const Span old_panels = ntree->socket_panels(); - ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num - 1, - __func__); - --ntree->socket_panels_num; - const MutableSpan new_panels = ntree->socket_panels_for_write(); - - Span old_panels_front = old_panels.take_front(index); - Span old_panels_back = old_panels.drop_front(index + 1); - std::copy(old_panels_front.begin(), old_panels_front.end(), new_panels.data()); - std::copy(old_panels_back.begin(), old_panels_back.end(), new_panels.drop_front(index).data()); - - MEM_SAFE_FREE(old_panels_array); - ntreeEnsureSocketInterfacePanelOrder(ntree); } void ntreeClearSocketPanels(bNodeTree *ntree) { - MEM_SAFE_FREE(ntree->socket_panels_array); - ntree->socket_panels_array = nullptr; - ntree->socket_panels_num = 0; - + LISTBASE_FOREACH (bNodeSocketPanel *, panel, &ntree->socket_panels) { + MEM_SAFE_FREE(panel->name); + } + BLI_freelistN(&ntree->socket_panels); /* No need to sort sockets, only null panel exists, relative order remains unchanged. */ } -void ntreeMoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel, int new_index) +void ntreeMoveSocketPanel(bNodeTree *ntree, int from_index, int to_index) { - if (!ntree->socket_panels().contains_ptr(panel)) { - return; + if (BLI_listbase_move_index(&ntree->socket_panels, from_index, to_index)) { + ntreeEnsureSocketInterfacePanelOrder(ntree); } - - const MutableSpan panels = ntree->socket_panels_for_write(); - const int old_index = panel - ntree->socket_panels_array; - if (old_index == new_index) { - return; - } - else if (old_index < new_index) { - const Span moved_panels = panels.slice(old_index + 1, new_index - old_index); - const bNodeSocketPanel tmp = panels[old_index]; - std::copy(moved_panels.begin(), moved_panels.end(), panels.drop_front(old_index).data()); - panels[new_index] = tmp; - } - else /* old_index > new_index */ { - const Span moved_panels = panels.slice(new_index, old_index - new_index); - const bNodeSocketPanel tmp = panels[old_index]; - std::copy_backward( - moved_panels.begin(), moved_panels.end(), panels.drop_front(old_index + 1).data()); - panels[new_index] = tmp; - } - - ntreeEnsureSocketInterfacePanelOrder(ntree); } namespace blender::bke { diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 656a62320bc..b525d7c074a 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -536,6 +536,8 @@ typedef struct bNodeLink { /** Panel in node tree for grouping sockets. */ typedef struct bNodeSocketPanel { + struct bNodeSocketPanel *next, *prev; + char *name; int flag; int identifier; @@ -605,11 +607,9 @@ typedef struct bNodeTree { struct PreviewImage *preview; /* UI panels for sockets */ - struct bNodeSocketPanel *socket_panels_array; - int socket_panels_num; + ListBase socket_panels; int active_socket_panel; int next_socket_panel_identifier; - char _pad2[4]; bNodeTreeRuntimeHandle *runtime; @@ -674,9 +674,6 @@ typedef struct bNodeTree { /** Inputs and outputs of the entire node group. */ blender::Span interface_inputs() const; blender::Span interface_outputs() const; - - blender::Span socket_panels() const; - blender::MutableSpan socket_panels_for_write(); #endif } bNodeTree; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index e8ef0d479c7..240d4003598 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3188,12 +3188,9 @@ static void rna_NodeSocketInterface_panel_set(PointerRNA *ptr, bNodeTree *ntree = (bNodeTree *)ptr->owner_id; bNodeSocketPanel *panel = (bNodeSocketPanel *)value.data; - if (panel != NULL) { - const int64_t index = panel - ntree->socket_panels_array; - if (index < 0 || index >= ntree->socket_panels_num) { - BKE_report(reports, RPT_ERROR, "Panel is not in the node tree interface"); - return; - } + if (panel && BLI_findindex(&ntree->socket_panels, panel) < 0) { + BKE_report(reports, RPT_ERROR, "Panel is not in the node tree interface"); + return; } ntreeSetSocketInterfacePanel(ntree, socket, panel); @@ -3207,8 +3204,7 @@ static bool rna_NodeSocketInterface_panel_poll(PointerRNA *ptr, PointerRNA value return true; } - const int64_t index = panel - ntree->socket_panels_array; - if (index < 0 || index >= ntree->socket_panels_num) { + if (BLI_findindex(&ntree->socket_panels, panel) < 0) { return false; } @@ -3387,13 +3383,7 @@ static void rna_NodeTree_socket_panels_move(bNodeTree *ntree, int from_index, int to_index) { - if (from_index < 0 || from_index >= ntree->socket_panels_num || to_index < 0 || - to_index >= ntree->socket_panels_num) - { - return; - } - - ntreeMoveSocketPanel(ntree, &ntree->socket_panels_array[from_index], to_index); + ntreeMoveSocketPanel(ntree, from_index, to_index); BKE_ntree_update_tag_interface(ntree); ED_node_tree_propagate_change(NULL, bmain, ntree); @@ -3403,12 +3393,7 @@ static void rna_NodeTree_socket_panels_move(bNodeTree *ntree, static PointerRNA rna_NodeTree_active_socket_panel_get(PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->data; - bNodeSocketPanel *panel = NULL; - if (ntree->active_socket_panel >= 0 && - ntree->active_socket_panel < ntree->socket_panels_num) - { - panel = &ntree->socket_panels_array[ntree->active_socket_panel]; - } + bNodeSocketPanel *panel = BLI_findlink(&ntree->socket_panels, ntree->active_socket_panel); PointerRNA r_ptr; RNA_pointer_create(ptr->owner_id, &RNA_NodeSocketPanel, panel, &r_ptr); @@ -3421,7 +3406,7 @@ static void rna_NodeTree_active_socket_panel_set(PointerRNA *ptr, { bNodeSocketPanel *panel = (bNodeSocketPanel *)value.data; bNodeTree *ntree = (bNodeTree *)ptr->data; - ntree->active_socket_panel = panel - ntree->socket_panels_array; + ntree->active_socket_panel = BLI_findindex(&ntree->socket_panels, panel); } /* ******** Node Types ******** */ @@ -13350,7 +13335,7 @@ static void rna_def_nodetree(BlenderRNA *brna) RNA_def_property_update(prop, NC_NODE, NULL); prop = RNA_def_property(srna, "socket_panels", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "socket_panels_array", "socket_panels_num"); + RNA_def_property_collection_sdna(prop, NULL, "socket_panels", NULL); RNA_def_property_struct_type(prop, "NodeSocketPanel"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text( -- 2.30.2 From 48d9028fdac23f16f58643ec41080067841d2270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Thu, 8 Jun 2023 14:12:04 +0200 Subject: [PATCH 11/22] Revert "Switch from arrays to ListBase for the categories in node trees." This reverts commit 284a6bd094aa6d533cad341db6f347523ee6374c. --- source/blender/blenkernel/BKE_node.h | 5 +- source/blender/blenkernel/BKE_node_runtime.hh | 10 ++ source/blender/blenkernel/intern/node.cc | 139 ++++++++++++------ source/blender/makesdna/DNA_node_types.h | 9 +- source/blender/makesrna/intern/rna_nodetree.c | 31 +++- 5 files changed, 139 insertions(+), 55 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 4f861a74471..4fddbe6268d 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -590,10 +590,9 @@ void ntreeClearSocketPanels(bNodeTree *ntree); /** * Move a socket panel up or down in the node tree. - * \param from_index: Current index of the poanel to move. - * \param to_index: Index to which to move the panel. + * \param index: Index to which to move the panel. */ -void ntreeMoveSocketPanel(bNodeTree *ntree, int from_index, int to_index); +void ntreeMoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel, int new_index); /** \} */ diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index 629cf8c0c85..4ff9387be76 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -516,6 +516,16 @@ inline blender::Span bNodeTree::root_frames() const return this->runtime->root_frames; } +inline blender::Span bNodeTree::socket_panels() const +{ + return blender::Span(socket_panels_array, socket_panels_num); +} + +inline blender::MutableSpan bNodeTree::socket_panels_for_write() +{ + return blender::MutableSpan(socket_panels_array, socket_panels_num); +} + /* -------------------------------------------------------------------- */ /** \name #bNode Inline Methods * \{ */ diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 29bbffac049..431eae9ed59 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -643,9 +643,10 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree) write_node_socket_interface(writer, sock); } - LISTBASE_FOREACH (bNodeSocketPanel *, panel, &ntree->socket_panels) { - BLO_write_struct(writer, bNodeSocketPanel, panel); - BLO_write_string(writer, panel->name); + BLO_write_struct_array( + writer, bNodeSocketPanel, ntree->socket_panels_num, ntree->socket_panels_array); + for (const bNodeSocketPanel &panel : ntree->socket_panels()) { + BLO_write_string(writer, panel.name); } BKE_previewimg_blend_write(writer, ntree->preview); @@ -868,9 +869,9 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree) BLO_read_data_address(reader, &link->tosock); } - BLO_read_list(reader, &ntree->socket_panels); - LISTBASE_FOREACH (bNodeSocketPanel *, panel, &ntree->socket_panels) { - BLO_read_data_address(reader, &panel->name); + BLO_read_data_address(reader, &ntree->socket_panels_array); + for (bNodeSocketPanel &panel : ntree->socket_panels_for_write()) { + BLO_read_data_address(reader, &panel.name); } /* TODO: should be dealt by new generic cache handling of IDs... */ @@ -3681,27 +3682,25 @@ void ntreeEnsureSocketInterfacePanelOrder(bNodeTree *ntree) /* XXX Hack: store panel index in panel_id temporarily for sorting. */ LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->inputs) { const bNodeSocketPanel *panel = ntreeFindSocketPanelByID(ntree, iosock->panel_id); - iosock->panel_id = (panel == nullptr ? -1 : BLI_findindex(&ntree->socket_panels, panel)); + iosock->panel_id = panel == nullptr ? -1 : (int)(panel - ntree->socket_panels_array); } LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->outputs) { const bNodeSocketPanel *panel = ntreeFindSocketPanelByID(ntree, iosock->panel_id); - iosock->panel_id = panel == nullptr ? -1 : BLI_findindex(&ntree->socket_panels, panel); + iosock->panel_id = panel == nullptr ? -1 : (int)(panel - ntree->socket_panels_array); } BLI_listbase_sort(&ntree->inputs, blender::bke::node_socket_panel_cmp); BLI_listbase_sort(&ntree->outputs, blender::bke::node_socket_panel_cmp); /* Restore panel_id. */ LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->inputs) { if (iosock->panel_id >= 0) { - const bNodeSocketPanel *panel = static_cast( - BLI_findlink(&ntree->socket_panels, iosock->panel_id)); - iosock->panel_id = panel->identifier; + const bNodeSocketPanel &panel = ntree->socket_panels()[iosock->panel_id]; + iosock->panel_id = panel.identifier; } } LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->outputs) { if (iosock->panel_id >= 0) { - const bNodeSocketPanel *panel = static_cast( - BLI_findlink(&ntree->socket_panels, iosock->panel_id)); - iosock->panel_id = panel->identifier; + const bNodeSocketPanel &panel = ntree->socket_panels()[iosock->panel_id]; + iosock->panel_id = panel.identifier; } } } @@ -3819,9 +3818,9 @@ void ntreeRemoveSocketInterface(bNodeTree *ntree, bNodeSocket *sock) bNodeSocketPanel *ntreeFindSocketPanelByID(bNodeTree *ntree, int id) { - LISTBASE_FOREACH (bNodeSocketPanel *, panel, &ntree->socket_panels) { - if (panel->identifier == id) { - return panel; + for (bNodeSocketPanel &panel : ntree->socket_panels_for_write()) { + if (panel.identifier == id) { + return &panel; } } return nullptr; @@ -3829,53 +3828,111 @@ bNodeSocketPanel *ntreeFindSocketPanelByID(bNodeTree *ntree, int id) bNodeSocketPanel *ntreeAddSocketPanel(bNodeTree *ntree, const char *name, int flag) { - bNodeSocketPanel *new_panel = MEM_cnew(__func__); - new_panel->name = BLI_strdup(name); - new_panel->flag = flag; - new_panel->identifier = ntree->next_socket_panel_identifier++; + bNodeSocketPanel *old_panels_array = ntree->socket_panels_array; + const Span old_panels = ntree->socket_panels(); + ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num + 1, + __func__); + ++ntree->socket_panels_num; + const MutableSpan new_panels = ntree->socket_panels_for_write(); + + std::copy(old_panels.begin(), old_panels.end(), new_panels.data()); + bNodeSocketPanel &new_panel = new_panels[new_panels.size() - 1]; + new_panel = {BLI_strdup(name), flag, ntree->next_socket_panel_identifier++}; + + MEM_SAFE_FREE(old_panels_array); - BLI_addtail(&ntree->socket_panels, new_panel); /* No need to sort sockets, nothing is using the new panel yet */ - return new_panel; + + return &new_panel; } bNodeSocketPanel *ntreeInsertSocketPanel(bNodeTree *ntree, const char *name, int flag, int index) { - bNodeSocketPanel *new_panel = MEM_cnew(__func__); - new_panel->name = BLI_strdup(name); - new_panel->flag = flag; - new_panel->identifier = ntree->next_socket_panel_identifier++; + if (!blender::IndexRange(ntree->socket_panels().size() + 1).contains(index)) { + return nullptr; + } + + bNodeSocketPanel *old_panels_array = ntree->socket_panels_array; + const Span old_panels = ntree->socket_panels(); + ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num + 1, + __func__); + ++ntree->socket_panels_num; + const MutableSpan new_panels = ntree->socket_panels_for_write(); + + Span old_panels_front = old_panels.take_front(index); + Span old_panels_back = old_panels.drop_front(index); + std::copy(old_panels_front.begin(), old_panels_front.end(), new_panels.data()); + std::copy( + old_panels_back.begin(), old_panels_back.end(), new_panels.drop_front(index + 1).data()); + bNodeSocketPanel &new_panel = new_panels[index]; + new_panel = {BLI_strdup(name), flag, ntree->next_socket_panel_identifier++}; + + MEM_SAFE_FREE(old_panels_array); - bNodeSocketPanel *panel_after = static_cast( - BLI_findlink(&ntree->socket_panels, index)); - BLI_insertlinkbefore(&ntree->socket_panels, panel_after, new_panel); /* No need to sort sockets, nothing is using the new panel yet */ - return new_panel; + + return &new_panel; } void ntreeRemoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel) { - if (BLI_remlink_safe(&ntree->socket_panels, panel)) { - MEM_SAFE_FREE(panel->name); - MEM_delete(panel); + const int index = panel - ntree->socket_panels_array; + if (!ntree->socket_panels().contains_ptr(panel)) { + return; } + + bNodeSocketPanel *old_panels_array = ntree->socket_panels_array; + const Span old_panels = ntree->socket_panels(); + ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num - 1, + __func__); + --ntree->socket_panels_num; + const MutableSpan new_panels = ntree->socket_panels_for_write(); + + Span old_panels_front = old_panels.take_front(index); + Span old_panels_back = old_panels.drop_front(index + 1); + std::copy(old_panels_front.begin(), old_panels_front.end(), new_panels.data()); + std::copy(old_panels_back.begin(), old_panels_back.end(), new_panels.drop_front(index).data()); + + MEM_SAFE_FREE(old_panels_array); + ntreeEnsureSocketInterfacePanelOrder(ntree); } void ntreeClearSocketPanels(bNodeTree *ntree) { - LISTBASE_FOREACH (bNodeSocketPanel *, panel, &ntree->socket_panels) { - MEM_SAFE_FREE(panel->name); - } - BLI_freelistN(&ntree->socket_panels); + MEM_SAFE_FREE(ntree->socket_panels_array); + ntree->socket_panels_array = nullptr; + ntree->socket_panels_num = 0; + /* No need to sort sockets, only null panel exists, relative order remains unchanged. */ } -void ntreeMoveSocketPanel(bNodeTree *ntree, int from_index, int to_index) +void ntreeMoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel, int new_index) { - if (BLI_listbase_move_index(&ntree->socket_panels, from_index, to_index)) { - ntreeEnsureSocketInterfacePanelOrder(ntree); + if (!ntree->socket_panels().contains_ptr(panel)) { + return; } + + const MutableSpan panels = ntree->socket_panels_for_write(); + const int old_index = panel - ntree->socket_panels_array; + if (old_index == new_index) { + return; + } + else if (old_index < new_index) { + const Span moved_panels = panels.slice(old_index + 1, new_index - old_index); + const bNodeSocketPanel tmp = panels[old_index]; + std::copy(moved_panels.begin(), moved_panels.end(), panels.drop_front(old_index).data()); + panels[new_index] = tmp; + } + else /* old_index > new_index */ { + const Span moved_panels = panels.slice(new_index, old_index - new_index); + const bNodeSocketPanel tmp = panels[old_index]; + std::copy_backward( + moved_panels.begin(), moved_panels.end(), panels.drop_front(old_index + 1).data()); + panels[new_index] = tmp; + } + + ntreeEnsureSocketInterfacePanelOrder(ntree); } namespace blender::bke { diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index b525d7c074a..656a62320bc 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -536,8 +536,6 @@ typedef struct bNodeLink { /** Panel in node tree for grouping sockets. */ typedef struct bNodeSocketPanel { - struct bNodeSocketPanel *next, *prev; - char *name; int flag; int identifier; @@ -607,9 +605,11 @@ typedef struct bNodeTree { struct PreviewImage *preview; /* UI panels for sockets */ - ListBase socket_panels; + struct bNodeSocketPanel *socket_panels_array; + int socket_panels_num; int active_socket_panel; int next_socket_panel_identifier; + char _pad2[4]; bNodeTreeRuntimeHandle *runtime; @@ -674,6 +674,9 @@ typedef struct bNodeTree { /** Inputs and outputs of the entire node group. */ blender::Span interface_inputs() const; blender::Span interface_outputs() const; + + blender::Span socket_panels() const; + blender::MutableSpan socket_panels_for_write(); #endif } bNodeTree; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 240d4003598..e8ef0d479c7 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3188,9 +3188,12 @@ static void rna_NodeSocketInterface_panel_set(PointerRNA *ptr, bNodeTree *ntree = (bNodeTree *)ptr->owner_id; bNodeSocketPanel *panel = (bNodeSocketPanel *)value.data; - if (panel && BLI_findindex(&ntree->socket_panels, panel) < 0) { - BKE_report(reports, RPT_ERROR, "Panel is not in the node tree interface"); - return; + if (panel != NULL) { + const int64_t index = panel - ntree->socket_panels_array; + if (index < 0 || index >= ntree->socket_panels_num) { + BKE_report(reports, RPT_ERROR, "Panel is not in the node tree interface"); + return; + } } ntreeSetSocketInterfacePanel(ntree, socket, panel); @@ -3204,7 +3207,8 @@ static bool rna_NodeSocketInterface_panel_poll(PointerRNA *ptr, PointerRNA value return true; } - if (BLI_findindex(&ntree->socket_panels, panel) < 0) { + const int64_t index = panel - ntree->socket_panels_array; + if (index < 0 || index >= ntree->socket_panels_num) { return false; } @@ -3383,7 +3387,13 @@ static void rna_NodeTree_socket_panels_move(bNodeTree *ntree, int from_index, int to_index) { - ntreeMoveSocketPanel(ntree, from_index, to_index); + if (from_index < 0 || from_index >= ntree->socket_panels_num || to_index < 0 || + to_index >= ntree->socket_panels_num) + { + return; + } + + ntreeMoveSocketPanel(ntree, &ntree->socket_panels_array[from_index], to_index); BKE_ntree_update_tag_interface(ntree); ED_node_tree_propagate_change(NULL, bmain, ntree); @@ -3393,7 +3403,12 @@ static void rna_NodeTree_socket_panels_move(bNodeTree *ntree, static PointerRNA rna_NodeTree_active_socket_panel_get(PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->data; - bNodeSocketPanel *panel = BLI_findlink(&ntree->socket_panels, ntree->active_socket_panel); + bNodeSocketPanel *panel = NULL; + if (ntree->active_socket_panel >= 0 && + ntree->active_socket_panel < ntree->socket_panels_num) + { + panel = &ntree->socket_panels_array[ntree->active_socket_panel]; + } PointerRNA r_ptr; RNA_pointer_create(ptr->owner_id, &RNA_NodeSocketPanel, panel, &r_ptr); @@ -3406,7 +3421,7 @@ static void rna_NodeTree_active_socket_panel_set(PointerRNA *ptr, { bNodeSocketPanel *panel = (bNodeSocketPanel *)value.data; bNodeTree *ntree = (bNodeTree *)ptr->data; - ntree->active_socket_panel = BLI_findindex(&ntree->socket_panels, panel); + ntree->active_socket_panel = panel - ntree->socket_panels_array; } /* ******** Node Types ******** */ @@ -13335,7 +13350,7 @@ static void rna_def_nodetree(BlenderRNA *brna) RNA_def_property_update(prop, NC_NODE, NULL); prop = RNA_def_property(srna, "socket_panels", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "socket_panels", NULL); + RNA_def_property_collection_sdna(prop, NULL, "socket_panels_array", "socket_panels_num"); RNA_def_property_struct_type(prop, "NodeSocketPanel"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text( -- 2.30.2 From ab0d8761d2e54fd26ce7adae4e218877b7dfcb99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Thu, 8 Jun 2023 16:55:32 +0200 Subject: [PATCH 12/22] Use array of pointers for node panels instead plain array. This has the advantage that pointers to panel declarations remain valid after most panel API functions. This is important for python scripting where a panel is referenced by pointer internally. --- source/blender/blenkernel/BKE_node.h | 12 ++ source/blender/blenkernel/BKE_node_runtime.hh | 4 +- source/blender/blenkernel/intern/node.cc | 114 +++++++++++------- source/blender/makesdna/DNA_node_types.h | 6 +- source/blender/makesrna/intern/rna_nodetree.c | 25 ++-- 5 files changed, 92 insertions(+), 69 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 4fddbe6268d..015933db8dd 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -561,6 +561,18 @@ void ntreeSetSocketInterfacePanel(bNodeTree *ntree, bNodeSocket *sock, bNodeSock /** \name Node Tree Socket Panels * \{ */ +/** + * Check if a panel is part of the node tree. + * \return True if the panel is part of the node tree. + */ +bool ntreeContainsSocketPanel(const bNodeTree *ntree, const bNodeSocketPanel *panel); + +/** + * Index of a panel in the node tree. + * \return Index of the panel in the node tree or -1 if the tree does not contain the panel. + */ +int ntreeGetSocketPanelIndex(const bNodeTree *ntree, const bNodeSocketPanel *panel); + /** * Find a socket panel by its unique ID. * \param id: Unique ID of the panel within the node tree. diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index 4ff9387be76..f76724e1e13 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -516,12 +516,12 @@ inline blender::Span bNodeTree::root_frames() const return this->runtime->root_frames; } -inline blender::Span bNodeTree::socket_panels() const +inline blender::Span bNodeTree::socket_panels() const { return blender::Span(socket_panels_array, socket_panels_num); } -inline blender::MutableSpan bNodeTree::socket_panels_for_write() +inline blender::MutableSpan bNodeTree::socket_panels_for_write() { return blender::MutableSpan(socket_panels_array, socket_panels_num); } diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 431eae9ed59..d9d3defea05 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -643,10 +643,10 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree) write_node_socket_interface(writer, sock); } - BLO_write_struct_array( - writer, bNodeSocketPanel, ntree->socket_panels_num, ntree->socket_panels_array); - for (const bNodeSocketPanel &panel : ntree->socket_panels()) { - BLO_write_string(writer, panel.name); + BLO_write_pointer_array(writer, ntree->socket_panels_num, ntree->socket_panels_array); + for (const bNodeSocketPanel *panel : ntree->socket_panels()) { + BLO_write_struct(writer, bNodeSocketPanel, panel); + BLO_write_string(writer, panel->name); } BKE_previewimg_blend_write(writer, ntree->preview); @@ -869,9 +869,10 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree) BLO_read_data_address(reader, &link->tosock); } - BLO_read_data_address(reader, &ntree->socket_panels_array); - for (bNodeSocketPanel &panel : ntree->socket_panels_for_write()) { - BLO_read_data_address(reader, &panel.name); + BLO_read_pointer_array(reader, reinterpret_cast(&ntree->socket_panels_array)); + for (const int i : IndexRange(ntree->socket_panels_num)) { + BLO_read_data_address(reader, &ntree->socket_panels_array[i]); + BLO_read_data_address(reader, &ntree->socket_panels_array[i]->name); } /* TODO: should be dealt by new generic cache handling of IDs... */ @@ -3682,25 +3683,25 @@ void ntreeEnsureSocketInterfacePanelOrder(bNodeTree *ntree) /* XXX Hack: store panel index in panel_id temporarily for sorting. */ LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->inputs) { const bNodeSocketPanel *panel = ntreeFindSocketPanelByID(ntree, iosock->panel_id); - iosock->panel_id = panel == nullptr ? -1 : (int)(panel - ntree->socket_panels_array); + iosock->panel_id = ntreeGetSocketPanelIndex(ntree, panel); } LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->outputs) { const bNodeSocketPanel *panel = ntreeFindSocketPanelByID(ntree, iosock->panel_id); - iosock->panel_id = panel == nullptr ? -1 : (int)(panel - ntree->socket_panels_array); + iosock->panel_id = ntreeGetSocketPanelIndex(ntree, panel); } BLI_listbase_sort(&ntree->inputs, blender::bke::node_socket_panel_cmp); BLI_listbase_sort(&ntree->outputs, blender::bke::node_socket_panel_cmp); /* Restore panel_id. */ LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->inputs) { if (iosock->panel_id >= 0) { - const bNodeSocketPanel &panel = ntree->socket_panels()[iosock->panel_id]; - iosock->panel_id = panel.identifier; + const bNodeSocketPanel *panel = ntree->socket_panels()[iosock->panel_id]; + iosock->panel_id = panel->identifier; } } LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->outputs) { if (iosock->panel_id >= 0) { - const bNodeSocketPanel &panel = ntree->socket_panels()[iosock->panel_id]; - iosock->panel_id = panel.identifier; + const bNodeSocketPanel *panel = ntree->socket_panels()[iosock->panel_id]; + iosock->panel_id = panel->identifier; } } } @@ -3816,11 +3817,21 @@ void ntreeRemoveSocketInterface(bNodeTree *ntree, bNodeSocket *sock) BKE_ntree_update_tag_interface(ntree); } +bool ntreeContainsSocketPanel(const bNodeTree *ntree, const bNodeSocketPanel *panel) +{ + return ntree->socket_panels().contains(const_cast(panel)); +} + +int ntreeGetSocketPanelIndex(const bNodeTree *ntree, const bNodeSocketPanel *panel) +{ + return ntree->socket_panels().first_index_try(const_cast(panel)); +} + bNodeSocketPanel *ntreeFindSocketPanelByID(bNodeTree *ntree, int id) { - for (bNodeSocketPanel &panel : ntree->socket_panels_for_write()) { - if (panel.identifier == id) { - return &panel; + for (bNodeSocketPanel *panel : ntree->socket_panels_for_write()) { + if (panel->identifier == id) { + return panel; } } return nullptr; @@ -3828,22 +3839,24 @@ bNodeSocketPanel *ntreeFindSocketPanelByID(bNodeTree *ntree, int id) bNodeSocketPanel *ntreeAddSocketPanel(bNodeTree *ntree, const char *name, int flag) { - bNodeSocketPanel *old_panels_array = ntree->socket_panels_array; - const Span old_panels = ntree->socket_panels(); - ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num + 1, - __func__); + bNodeSocketPanel **old_panels_array = ntree->socket_panels_array; + const Span old_panels = ntree->socket_panels(); + ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num + 1, + __func__); ++ntree->socket_panels_num; - const MutableSpan new_panels = ntree->socket_panels_for_write(); + const MutableSpan new_panels = ntree->socket_panels_for_write(); std::copy(old_panels.begin(), old_panels.end(), new_panels.data()); - bNodeSocketPanel &new_panel = new_panels[new_panels.size() - 1]; - new_panel = {BLI_strdup(name), flag, ntree->next_socket_panel_identifier++}; + + bNodeSocketPanel *new_panel = MEM_cnew(__func__); + *new_panel = {BLI_strdup(name), flag, ntree->next_socket_panel_identifier++}; + new_panels[new_panels.size() - 1] = new_panel; MEM_SAFE_FREE(old_panels_array); /* No need to sort sockets, nothing is using the new panel yet */ - return &new_panel; + return new_panel; } bNodeSocketPanel *ntreeInsertSocketPanel(bNodeTree *ntree, const char *name, int flag, int index) @@ -3852,47 +3865,51 @@ bNodeSocketPanel *ntreeInsertSocketPanel(bNodeTree *ntree, const char *name, int return nullptr; } - bNodeSocketPanel *old_panels_array = ntree->socket_panels_array; - const Span old_panels = ntree->socket_panels(); - ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num + 1, - __func__); + bNodeSocketPanel **old_panels_array = ntree->socket_panels_array; + const Span old_panels = ntree->socket_panels(); + ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num + 1, + __func__); ++ntree->socket_panels_num; - const MutableSpan new_panels = ntree->socket_panels_for_write(); + const MutableSpan new_panels = ntree->socket_panels_for_write(); Span old_panels_front = old_panels.take_front(index); Span old_panels_back = old_panels.drop_front(index); std::copy(old_panels_front.begin(), old_panels_front.end(), new_panels.data()); std::copy( old_panels_back.begin(), old_panels_back.end(), new_panels.drop_front(index + 1).data()); - bNodeSocketPanel &new_panel = new_panels[index]; - new_panel = {BLI_strdup(name), flag, ntree->next_socket_panel_identifier++}; + + bNodeSocketPanel *new_panel = MEM_cnew(__func__); + *new_panel = {BLI_strdup(name), flag, ntree->next_socket_panel_identifier++}; + new_panels[index] = new_panel; MEM_SAFE_FREE(old_panels_array); /* No need to sort sockets, nothing is using the new panel yet */ - return &new_panel; + return new_panel; } void ntreeRemoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel) { - const int index = panel - ntree->socket_panels_array; - if (!ntree->socket_panels().contains_ptr(panel)) { + const int index = ntreeGetSocketPanelIndex(ntree, panel); + if (index < 0) { return; } - bNodeSocketPanel *old_panels_array = ntree->socket_panels_array; - const Span old_panels = ntree->socket_panels(); - ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num - 1, - __func__); + bNodeSocketPanel **old_panels_array = ntree->socket_panels_array; + const Span old_panels = ntree->socket_panels(); + ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num - 1, + __func__); --ntree->socket_panels_num; - const MutableSpan new_panels = ntree->socket_panels_for_write(); + const MutableSpan new_panels = ntree->socket_panels_for_write(); Span old_panels_front = old_panels.take_front(index); Span old_panels_back = old_panels.drop_front(index + 1); std::copy(old_panels_front.begin(), old_panels_front.end(), new_panels.data()); std::copy(old_panels_back.begin(), old_panels_back.end(), new_panels.drop_front(index).data()); + MEM_SAFE_FREE(panel->name); + MEM_SAFE_FREE(panel); MEM_SAFE_FREE(old_panels_array); ntreeEnsureSocketInterfacePanelOrder(ntree); @@ -3900,6 +3917,10 @@ void ntreeRemoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel) void ntreeClearSocketPanels(bNodeTree *ntree) { + for (bNodeSocketPanel *panel : ntree->socket_panels_for_write()) { + MEM_SAFE_FREE(panel->name); + MEM_SAFE_FREE(panel); + } MEM_SAFE_FREE(ntree->socket_panels_array); ntree->socket_panels_array = nullptr; ntree->socket_panels_num = 0; @@ -3909,24 +3930,25 @@ void ntreeClearSocketPanels(bNodeTree *ntree) void ntreeMoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel, int new_index) { - if (!ntree->socket_panels().contains_ptr(panel)) { + const int old_index = ntreeGetSocketPanelIndex(ntree, panel); + if (old_index < 0) { return; } - const MutableSpan panels = ntree->socket_panels_for_write(); - const int old_index = panel - ntree->socket_panels_array; + const MutableSpan panels = ntree->socket_panels_for_write(); if (old_index == new_index) { return; } else if (old_index < new_index) { - const Span moved_panels = panels.slice(old_index + 1, new_index - old_index); - const bNodeSocketPanel tmp = panels[old_index]; + const Span moved_panels = panels.slice(old_index + 1, + new_index - old_index); + bNodeSocketPanel *tmp = panels[old_index]; std::copy(moved_panels.begin(), moved_panels.end(), panels.drop_front(old_index).data()); panels[new_index] = tmp; } else /* old_index > new_index */ { - const Span moved_panels = panels.slice(new_index, old_index - new_index); - const bNodeSocketPanel tmp = panels[old_index]; + const Span moved_panels = panels.slice(new_index, old_index - new_index); + bNodeSocketPanel *tmp = panels[old_index]; std::copy_backward( moved_panels.begin(), moved_panels.end(), panels.drop_front(old_index + 1).data()); panels[new_index] = tmp; diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 656a62320bc..15fb28687a2 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -605,7 +605,7 @@ typedef struct bNodeTree { struct PreviewImage *preview; /* UI panels for sockets */ - struct bNodeSocketPanel *socket_panels_array; + struct bNodeSocketPanel **socket_panels_array; int socket_panels_num; int active_socket_panel; int next_socket_panel_identifier; @@ -675,8 +675,8 @@ typedef struct bNodeTree { blender::Span interface_inputs() const; blender::Span interface_outputs() const; - blender::Span socket_panels() const; - blender::MutableSpan socket_panels_for_write(); + blender::Span socket_panels() const; + blender::MutableSpan socket_panels_for_write(); #endif } bNodeTree; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index e8ef0d479c7..a8072f933b1 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3188,12 +3188,9 @@ static void rna_NodeSocketInterface_panel_set(PointerRNA *ptr, bNodeTree *ntree = (bNodeTree *)ptr->owner_id; bNodeSocketPanel *panel = (bNodeSocketPanel *)value.data; - if (panel != NULL) { - const int64_t index = panel - ntree->socket_panels_array; - if (index < 0 || index >= ntree->socket_panels_num) { - BKE_report(reports, RPT_ERROR, "Panel is not in the node tree interface"); - return; - } + if (panel && !ntreeContainsSocketPanel(ntree, panel)) { + BKE_report(reports, RPT_ERROR, "Panel is not in the node tree interface"); + return; } ntreeSetSocketInterfacePanel(ntree, socket, panel); @@ -3203,16 +3200,8 @@ static bool rna_NodeSocketInterface_panel_poll(PointerRNA *ptr, PointerRNA value { bNodeTree *ntree = (bNodeTree *)ptr->owner_id; bNodeSocketPanel *panel = (bNodeSocketPanel *)value.data; - if (panel == NULL) { - return true; - } - const int64_t index = panel - ntree->socket_panels_array; - if (index < 0 || index >= ntree->socket_panels_num) { - return false; - } - - return true; + return panel == NULL || ntreeContainsSocketPanel(ntree, panel); } static void rna_NodeSocketInterface_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) @@ -3393,7 +3382,7 @@ static void rna_NodeTree_socket_panels_move(bNodeTree *ntree, return; } - ntreeMoveSocketPanel(ntree, &ntree->socket_panels_array[from_index], to_index); + ntreeMoveSocketPanel(ntree, ntree->socket_panels_array[from_index], to_index); BKE_ntree_update_tag_interface(ntree); ED_node_tree_propagate_change(NULL, bmain, ntree); @@ -3407,7 +3396,7 @@ static PointerRNA rna_NodeTree_active_socket_panel_get(PointerRNA *ptr) if (ntree->active_socket_panel >= 0 && ntree->active_socket_panel < ntree->socket_panels_num) { - panel = &ntree->socket_panels_array[ntree->active_socket_panel]; + panel = ntree->socket_panels_array[ntree->active_socket_panel]; } PointerRNA r_ptr; @@ -3421,7 +3410,7 @@ static void rna_NodeTree_active_socket_panel_set(PointerRNA *ptr, { bNodeSocketPanel *panel = (bNodeSocketPanel *)value.data; bNodeTree *ntree = (bNodeTree *)ptr->data; - ntree->active_socket_panel = panel - ntree->socket_panels_array; + ntree->active_socket_panel = ntreeGetSocketPanelIndex(ntree, panel); } /* ******** Node Types ******** */ -- 2.30.2 From 661be297f03079dd76614c1bb1c6f82adc8c508d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Thu, 8 Jun 2023 18:11:31 +0200 Subject: [PATCH 13/22] Replace panel_id in node tree interface sockets with a simple pointer. --- source/blender/CMakeLists.txt | 1 - source/blender/blenkernel/intern/node.cc | 70 ++++++++++--------- .../blenloader/intern/versioning_400.cc | 12 ---- .../blender/editors/space_node/node_edit.cc | 2 +- source/blender/makesdna/DNA_node_defaults.h | 23 ------ source/blender/makesdna/DNA_node_types.h | 5 +- source/blender/makesdna/intern/dna_defaults.c | 1 - source/blender/makesrna/intern/rna_nodetree.c | 13 +--- 8 files changed, 42 insertions(+), 85 deletions(-) delete mode 100644 source/blender/makesdna/DNA_node_defaults.h diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index b17501c8bb1..3f0fc409a44 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -115,7 +115,6 @@ set(SRC_DNA_DEFAULTS_INC ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_meta_defaults.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_modifier_defaults.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_movieclip_defaults.h - ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_node_defaults.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_defaults.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_particle_defaults.h ${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_pointcloud_defaults.h diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index d9d3defea05..e6336eae6a2 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -677,6 +677,7 @@ static void direct_link_node_socket(BlendDataReader *reader, bNodeSocket *sock) BLO_read_data_address(reader, &sock->storage); BLO_read_data_address(reader, &sock->default_value); BLO_read_data_address(reader, &sock->default_attribute_name); + BLO_read_data_address(reader, &sock->panel); sock->runtime = MEM_new(__func__); } @@ -3651,16 +3652,21 @@ static bNodeSocket *make_socket_interface(bNodeTree *ntree, STRNCPY(sock->name, name); sock->storage = nullptr; sock->flag |= SOCK_COLLAPSED; - sock->panel_id = -1; return sock; } -static int node_socket_panel_cmp(const void *a, const void *b) +using PanelIndexMap = blender::Map; + +static int node_socket_panel_cmp(void *panel_index_map_v, const void *a, const void *b) { + const PanelIndexMap &panel_index_map = *static_cast(panel_index_map_v); const bNodeSocket *sock_a = static_cast(a); const bNodeSocket *sock_b = static_cast(b); - return (sock_a->panel_id > sock_b->panel_id) ? 1 : 0; + return panel_index_map.lookup_default(sock_a->panel, -1) > + panel_index_map.lookup_default(sock_b->panel, -1) ? + 1 : + 0; } bNodeSocket *ntreeFindSocketInterface(bNodeTree *ntree, @@ -3680,30 +3686,14 @@ bNodeSocket *ntreeFindSocketInterface(bNodeTree *ntree, void ntreeEnsureSocketInterfacePanelOrder(bNodeTree *ntree) { - /* XXX Hack: store panel index in panel_id temporarily for sorting. */ - LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->inputs) { - const bNodeSocketPanel *panel = ntreeFindSocketPanelByID(ntree, iosock->panel_id); - iosock->panel_id = ntreeGetSocketPanelIndex(ntree, panel); - } - LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->outputs) { - const bNodeSocketPanel *panel = ntreeFindSocketPanelByID(ntree, iosock->panel_id); - iosock->panel_id = ntreeGetSocketPanelIndex(ntree, panel); - } - BLI_listbase_sort(&ntree->inputs, blender::bke::node_socket_panel_cmp); - BLI_listbase_sort(&ntree->outputs, blender::bke::node_socket_panel_cmp); - /* Restore panel_id. */ - LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->inputs) { - if (iosock->panel_id >= 0) { - const bNodeSocketPanel *panel = ntree->socket_panels()[iosock->panel_id]; - iosock->panel_id = panel->identifier; - } - } - LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->outputs) { - if (iosock->panel_id >= 0) { - const bNodeSocketPanel *panel = ntree->socket_panels()[iosock->panel_id]; - iosock->panel_id = panel->identifier; - } + /* Store panel index for sorting. */ + blender::Map panel_index_map; + int index = 0; + for (const bNodeSocketPanel *panel : ntree->socket_panels()) { + panel_index_map.add_new(panel, index++); } + BLI_listbase_sort_r(&ntree->inputs, blender::bke::node_socket_panel_cmp, &panel_index_map); + BLI_listbase_sort_r(&ntree->outputs, blender::bke::node_socket_panel_cmp, &panel_index_map); } bNodeSocket *ntreeAddSocketInterface(bNodeTree *ntree, @@ -3727,15 +3717,11 @@ bNodeSocket *ntreeAddSocketInterface(bNodeTree *ntree, void ntreeSetSocketInterfacePanel(bNodeTree *ntree, bNodeSocket *socket, bNodeSocketPanel *panel) { - if (panel == NULL) { - socket->panel_id = -1; - return; - } + BLI_assert(panel == nullptr || ntreeContainsSocketPanel(ntree, panel)); - socket->panel_id = panel->identifier; + socket->panel = panel; ntreeEnsureSocketInterfacePanelOrder(ntree); - BKE_ntree_update_tag_interface(ntree); } @@ -3896,6 +3882,18 @@ void ntreeRemoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel) return; } + /* Remove references */ + LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->inputs) { + if (iosock->panel == panel) { + iosock->panel = nullptr; + } + } + LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->outputs) { + if (iosock->panel == panel) { + iosock->panel = nullptr; + } + } + bNodeSocketPanel **old_panels_array = ntree->socket_panels_array; const Span old_panels = ntree->socket_panels(); ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num - 1, @@ -3917,6 +3915,14 @@ void ntreeRemoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel) void ntreeClearSocketPanels(bNodeTree *ntree) { + /* Remove references */ + LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->inputs) { + iosock->panel = nullptr; + } + LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->outputs) { + iosock->panel = nullptr; + } + for (bNodeSocketPanel *panel : ntree->socket_panels_for_write()) { MEM_SAFE_FREE(panel->name); MEM_SAFE_FREE(panel); diff --git a/source/blender/blenloader/intern/versioning_400.cc b/source/blender/blenloader/intern/versioning_400.cc index 8939faae962..d286f624fe1 100644 --- a/source/blender/blenloader/intern/versioning_400.cc +++ b/source/blender/blenloader/intern/versioning_400.cc @@ -212,18 +212,6 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain) } FOREACH_NODETREE_END; - if (!DNA_struct_elem_find(fd->filesdna, "bNodeSocket", "int", "panel_id")) { - FOREACH_NODETREE_BEGIN (bmain, ntree, id) { - LISTBASE_FOREACH (bNodeSocket *, socket, &ntree->inputs) { - socket->panel_id = -1; - } - LISTBASE_FOREACH (bNodeSocket *, socket, &ntree->outputs) { - socket->panel_id = -1; - } - } - FOREACH_NODETREE_END; - } - /* Keep this block, even when empty. */ } } diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc index de7919f19bd..36d69c285fb 100644 --- a/source/blender/editors/space_node/node_edit.cc +++ b/source/blender/editors/space_node/node_edit.cc @@ -2199,7 +2199,7 @@ static int ntree_socket_add_exec(bContext *C, wmOperator *op) /* XXX this only works for actual sockets, not interface templates! */ // nodeSocketCopyValue(sock, &ntree_ptr, active_sock, &ntree_ptr); /* Inherit socket panel from the active socket interface. */ - sock->panel_id = active_sock->panel_id; + sock->panel = active_sock->panel; } else { /* XXX TODO: define default socket type for a tree! */ diff --git a/source/blender/makesdna/DNA_node_defaults.h b/source/blender/makesdna/DNA_node_defaults.h deleted file mode 100644 index f63c0398f94..00000000000 --- a/source/blender/makesdna/DNA_node_defaults.h +++ /dev/null @@ -1,23 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/** \file - * \ingroup DNA - */ - -#pragma once - -/* Struct members on own line. */ -/* clang-format off */ - -/* -------------------------------------------------------------------- */ -/** \name bArmature Struct - * \{ */ - -#define _DNA_DEFAULT_bNodeSocket \ - { \ - .panel_id = -1, \ - } - -/** \} */ - -/* clang-format on */ diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 15fb28687a2..f4a61edbd9f 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -168,9 +168,8 @@ typedef struct bNodeSocket { /** Custom data for inputs, only UI writes in this. */ bNodeStack ns DNA_DEPRECATED; - /* ID of the UI panel of the socket. */ - int panel_id; - int _pad2; + /* UI panel of the socket. */ + struct bNodeSocketPanel *panel; bNodeSocketRuntimeHandle *runtime; diff --git a/source/blender/makesdna/intern/dna_defaults.c b/source/blender/makesdna/intern/dna_defaults.c index 6b96e753f58..d76b30e9506 100644 --- a/source/blender/makesdna/intern/dna_defaults.c +++ b/source/blender/makesdna/intern/dna_defaults.c @@ -126,7 +126,6 @@ #include "DNA_meta_defaults.h" #include "DNA_modifier_defaults.h" #include "DNA_movieclip_defaults.h" -#include "DNA_node_defaults.h" #include "DNA_object_defaults.h" #include "DNA_particle_defaults.h" #include "DNA_pointcloud_defaults.h" diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index a8072f933b1..5695fbcd167 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3169,17 +3169,6 @@ static IDProperty **rna_NodeSocketInterface_idprops(PointerRNA *ptr) return &sock->prop; } -static PointerRNA rna_NodeSocketInterface_panel_get(PointerRNA *ptr) -{ - bNodeSocket *socket = (bNodeSocket *)ptr->data; - bNodeTree *ntree = (bNodeTree *)ptr->owner_id; - bNodeSocketPanel *panel = ntreeFindSocketPanelByID(ntree, socket->panel_id); - - PointerRNA r_ptr; - RNA_pointer_create(&ntree->id, &RNA_NodeSocketPanel, panel, &r_ptr); - return r_ptr; -} - static void rna_NodeSocketInterface_panel_set(PointerRNA *ptr, PointerRNA value, struct ReportList *reports) @@ -11742,7 +11731,7 @@ static void rna_def_node_socket_interface(BlenderRNA *brna) prop = RNA_def_property(srna, "panel", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_funcs(prop, - "rna_NodeSocketInterface_panel_get", + NULL, "rna_NodeSocketInterface_panel_set", NULL, "rna_NodeSocketInterface_panel_poll"); -- 2.30.2 From 397e9f83a7c547ccd0618c98b5436d6d829f9c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Thu, 8 Jun 2023 18:17:48 +0200 Subject: [PATCH 14/22] Remove the panel identifier, it's no longer needed. --- source/blender/blenkernel/BKE_node.h | 6 ------ source/blender/blenkernel/intern/node.cc | 10 ---------- source/blender/makesdna/DNA_node_types.h | 2 +- 3 files changed, 1 insertion(+), 17 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 015933db8dd..700d31db943 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -573,12 +573,6 @@ bool ntreeContainsSocketPanel(const bNodeTree *ntree, const bNodeSocketPanel *pa */ int ntreeGetSocketPanelIndex(const bNodeTree *ntree, const bNodeSocketPanel *panel); -/** - * Find a socket panel by its unique ID. - * \param id: Unique ID of the panel within the node tree. - */ -bNodeSocketPanel *ntreeFindSocketPanelByID(bNodeTree *ntree, int id); - /** * Add a new socket panel to the node tree. * \param name: Name of the new panel. diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index e6336eae6a2..81321e276d6 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -3813,16 +3813,6 @@ int ntreeGetSocketPanelIndex(const bNodeTree *ntree, const bNodeSocketPanel *pan return ntree->socket_panels().first_index_try(const_cast(panel)); } -bNodeSocketPanel *ntreeFindSocketPanelByID(bNodeTree *ntree, int id) -{ - for (bNodeSocketPanel *panel : ntree->socket_panels_for_write()) { - if (panel->identifier == id) { - return panel; - } - } - return nullptr; -} - bNodeSocketPanel *ntreeAddSocketPanel(bNodeTree *ntree, const char *name, int flag) { bNodeSocketPanel **old_panels_array = ntree->socket_panels_array; diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index f4a61edbd9f..97e28d1d8c0 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -537,7 +537,7 @@ typedef struct bNodeLink { typedef struct bNodeSocketPanel { char *name; int flag; - int identifier; + int _pad; } bNodeSocketPanel; /* the basis for a Node tree, all links and nodes reside internal here */ -- 2.30.2 From 57f33fe5313c2aec1d91596912ee28f2f3a0eeec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Fri, 9 Jun 2023 10:57:42 +0200 Subject: [PATCH 15/22] Added missing copy and free code for socket panels in node trees. --- source/blender/blenkernel/intern/node.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 81321e276d6..884c4429179 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -202,6 +202,15 @@ static void ntree_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, cons BLI_addtail(&ntree_dst->outputs, dst_socket); } + /* copy panels */ + ntree_dst->socket_panels_array = static_cast( + MEM_dupallocN(ntree_src->socket_panels_array)); + ntree_dst->socket_panels_num = ntree_src->socket_panels_num; + for (bNodeSocketPanel *&panel_ptr : ntree_dst->socket_panels_for_write()) { + panel_ptr = static_cast(MEM_dupallocN(panel_ptr)); + panel_ptr->name = BLI_strdup(panel_ptr->name); + } + /* copy preview hash */ if (ntree_src->previews && (flag & LIB_ID_COPY_NO_PREVIEW) == 0) { bNodeInstanceHashIterator iter; @@ -276,6 +285,13 @@ static void ntree_free_data(ID *id) MEM_freeN(sock); } + /* free panels */ + for (bNodeSocketPanel *panel : ntree->socket_panels_for_write()) { + MEM_SAFE_FREE(panel->name); + MEM_SAFE_FREE(panel); + } + MEM_SAFE_FREE(ntree->socket_panels_array); + /* free preview hash */ if (ntree->previews) { BKE_node_instance_hash_free(ntree->previews, (bNodeInstanceValueFP)node_preview_free); -- 2.30.2 From f9003d386bf7f848ca945ba4d3a89de86a94e207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Fri, 9 Jun 2023 16:28:11 +0200 Subject: [PATCH 16/22] Renamed bNodeSocketPanel to just bNodePanel. While sockets will be the first thing to populate such panels there can be other things in future that go into them. --- source/blender/blenkernel/BKE_node.h | 26 ++-- source/blender/blenkernel/BKE_node_runtime.hh | 8 +- source/blender/blenkernel/intern/node.cc | 121 +++++++++--------- source/blender/makesdna/DNA_node_types.h | 20 +-- source/blender/makesrna/intern/rna_nodetree.c | 100 +++++++-------- 5 files changed, 135 insertions(+), 140 deletions(-) diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 53a8c5ae2d5..3a114843343 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -553,7 +553,7 @@ struct bNodeSocket *ntreeAddSocketInterface(struct bNodeTree *ntree, const char *name); /** Set the panel of the interface socket. */ -void ntreeSetSocketInterfacePanel(bNodeTree *ntree, bNodeSocket *sock, bNodeSocketPanel *panel); +void ntreeSetSocketInterfacePanel(bNodeTree *ntree, bNodeSocket *sock, bNodePanel *panel); /** \} */ @@ -565,40 +565,40 @@ void ntreeSetSocketInterfacePanel(bNodeTree *ntree, bNodeSocket *sock, bNodeSock * Check if a panel is part of the node tree. * \return True if the panel is part of the node tree. */ -bool ntreeContainsSocketPanel(const bNodeTree *ntree, const bNodeSocketPanel *panel); +bool ntreeContainsPanel(const bNodeTree *ntree, const bNodePanel *panel); /** * Index of a panel in the node tree. * \return Index of the panel in the node tree or -1 if the tree does not contain the panel. */ -int ntreeGetSocketPanelIndex(const bNodeTree *ntree, const bNodeSocketPanel *panel); +int ntreeGetPanelIndex(const bNodeTree *ntree, const bNodePanel *panel); /** - * Add a new socket panel to the node tree. + * Add a new panel to the node tree. * \param name: Name of the new panel. * \param flag: Flags of the new panel. */ -bNodeSocketPanel *ntreeAddSocketPanel(bNodeTree *ntree, const char *name, int flag); +bNodePanel *ntreeAddPanel(bNodeTree *ntree, const char *name, int flag); /** - * Insert a new socket panel in the node tree. + * Insert a new panel in the node tree. * \param name: Name of the new panel. * \param flag: Flags of the new panel. * \param index: Index at which to insert the panel. */ -bNodeSocketPanel *ntreeInsertSocketPanel(bNodeTree *ntree, const char *name, int flag, int index); +bNodePanel *ntreeInsertPanel(bNodeTree *ntree, const char *name, int flag, int index); -/** Remove a socket panel from the node tree. */ -void ntreeRemoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel); +/** Remove a panel from the node tree. */ +void ntreeRemovePanel(bNodeTree *ntree, bNodePanel *panel); -/** Remove all socket panels from the node tree. */ -void ntreeClearSocketPanels(bNodeTree *ntree); +/** Remove all panels from the node tree. */ +void ntreeClearPanels(bNodeTree *ntree); /** - * Move a socket panel up or down in the node tree. + * Move a panel up or down in the node tree. * \param index: Index to which to move the panel. */ -void ntreeMoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel, int new_index); +void ntreeMovePanel(bNodeTree *ntree, bNodePanel *panel, int new_index); /** \} */ diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index f76724e1e13..d787c916965 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -516,14 +516,14 @@ inline blender::Span bNodeTree::root_frames() const return this->runtime->root_frames; } -inline blender::Span bNodeTree::socket_panels() const +inline blender::Span bNodeTree::panels() const { - return blender::Span(socket_panels_array, socket_panels_num); + return blender::Span(panels_array, panels_num); } -inline blender::MutableSpan bNodeTree::socket_panels_for_write() +inline blender::MutableSpan bNodeTree::panels_for_write() { - return blender::MutableSpan(socket_panels_array, socket_panels_num); + return blender::MutableSpan(panels_array, panels_num); } /* -------------------------------------------------------------------- */ diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 884c4429179..adeef5c7af9 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -203,11 +203,10 @@ static void ntree_copy_data(Main * /*bmain*/, ID *id_dst, const ID *id_src, cons } /* copy panels */ - ntree_dst->socket_panels_array = static_cast( - MEM_dupallocN(ntree_src->socket_panels_array)); - ntree_dst->socket_panels_num = ntree_src->socket_panels_num; - for (bNodeSocketPanel *&panel_ptr : ntree_dst->socket_panels_for_write()) { - panel_ptr = static_cast(MEM_dupallocN(panel_ptr)); + ntree_dst->panels_array = static_cast(MEM_dupallocN(ntree_src->panels_array)); + ntree_dst->panels_num = ntree_src->panels_num; + for (bNodePanel *&panel_ptr : ntree_dst->panels_for_write()) { + panel_ptr = static_cast(MEM_dupallocN(panel_ptr)); panel_ptr->name = BLI_strdup(panel_ptr->name); } @@ -286,11 +285,11 @@ static void ntree_free_data(ID *id) } /* free panels */ - for (bNodeSocketPanel *panel : ntree->socket_panels_for_write()) { + for (bNodePanel *panel : ntree->panels_for_write()) { MEM_SAFE_FREE(panel->name); MEM_SAFE_FREE(panel); } - MEM_SAFE_FREE(ntree->socket_panels_array); + MEM_SAFE_FREE(ntree->panels_array); /* free preview hash */ if (ntree->previews) { @@ -659,9 +658,9 @@ void ntreeBlendWrite(BlendWriter *writer, bNodeTree *ntree) write_node_socket_interface(writer, sock); } - BLO_write_pointer_array(writer, ntree->socket_panels_num, ntree->socket_panels_array); - for (const bNodeSocketPanel *panel : ntree->socket_panels()) { - BLO_write_struct(writer, bNodeSocketPanel, panel); + BLO_write_pointer_array(writer, ntree->panels_num, ntree->panels_array); + for (const bNodePanel *panel : ntree->panels()) { + BLO_write_struct(writer, bNodePanel, panel); BLO_write_string(writer, panel->name); } @@ -886,10 +885,10 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree) BLO_read_data_address(reader, &link->tosock); } - BLO_read_pointer_array(reader, reinterpret_cast(&ntree->socket_panels_array)); - for (const int i : IndexRange(ntree->socket_panels_num)) { - BLO_read_data_address(reader, &ntree->socket_panels_array[i]); - BLO_read_data_address(reader, &ntree->socket_panels_array[i]->name); + BLO_read_pointer_array(reader, reinterpret_cast(&ntree->panels_array)); + for (const int i : IndexRange(ntree->panels_num)) { + BLO_read_data_address(reader, &ntree->panels_array[i]); + BLO_read_data_address(reader, &ntree->panels_array[i]->name); } /* TODO: should be dealt by new generic cache handling of IDs... */ @@ -3672,7 +3671,7 @@ static bNodeSocket *make_socket_interface(bNodeTree *ntree, return sock; } -using PanelIndexMap = blender::Map; +using PanelIndexMap = blender::Map; static int node_socket_panel_cmp(void *panel_index_map_v, const void *a, const void *b) { @@ -3703,9 +3702,9 @@ bNodeSocket *ntreeFindSocketInterface(bNodeTree *ntree, void ntreeEnsureSocketInterfacePanelOrder(bNodeTree *ntree) { /* Store panel index for sorting. */ - blender::Map panel_index_map; + blender::Map panel_index_map; int index = 0; - for (const bNodeSocketPanel *panel : ntree->socket_panels()) { + for (const bNodePanel *panel : ntree->panels()) { panel_index_map.add_new(panel, index++); } BLI_listbase_sort_r(&ntree->inputs, blender::bke::node_socket_panel_cmp, &panel_index_map); @@ -3731,9 +3730,9 @@ bNodeSocket *ntreeAddSocketInterface(bNodeTree *ntree, return iosock; } -void ntreeSetSocketInterfacePanel(bNodeTree *ntree, bNodeSocket *socket, bNodeSocketPanel *panel) +void ntreeSetSocketInterfacePanel(bNodeTree *ntree, bNodeSocket *socket, bNodePanel *panel) { - BLI_assert(panel == nullptr || ntreeContainsSocketPanel(ntree, panel)); + BLI_assert(panel == nullptr || ntreeContainsPanel(ntree, panel)); socket->panel = panel; @@ -3819,29 +3818,28 @@ void ntreeRemoveSocketInterface(bNodeTree *ntree, bNodeSocket *sock) BKE_ntree_update_tag_interface(ntree); } -bool ntreeContainsSocketPanel(const bNodeTree *ntree, const bNodeSocketPanel *panel) +bool ntreeContainsPanel(const bNodeTree *ntree, const bNodePanel *panel) { - return ntree->socket_panels().contains(const_cast(panel)); + return ntree->panels().contains(const_cast(panel)); } -int ntreeGetSocketPanelIndex(const bNodeTree *ntree, const bNodeSocketPanel *panel) +int ntreeGetPanelIndex(const bNodeTree *ntree, const bNodePanel *panel) { - return ntree->socket_panels().first_index_try(const_cast(panel)); + return ntree->panels().first_index_try(const_cast(panel)); } -bNodeSocketPanel *ntreeAddSocketPanel(bNodeTree *ntree, const char *name, int flag) +bNodePanel *ntreeAddPanel(bNodeTree *ntree, const char *name, int flag) { - bNodeSocketPanel **old_panels_array = ntree->socket_panels_array; - const Span old_panels = ntree->socket_panels(); - ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num + 1, - __func__); - ++ntree->socket_panels_num; - const MutableSpan new_panels = ntree->socket_panels_for_write(); + bNodePanel **old_panels_array = ntree->panels_array; + const Span old_panels = ntree->panels(); + ntree->panels_array = MEM_cnew_array(ntree->panels_num + 1, __func__); + ++ntree->panels_num; + const MutableSpan new_panels = ntree->panels_for_write(); std::copy(old_panels.begin(), old_panels.end(), new_panels.data()); - bNodeSocketPanel *new_panel = MEM_cnew(__func__); - *new_panel = {BLI_strdup(name), flag, ntree->next_socket_panel_identifier++}; + bNodePanel *new_panel = MEM_cnew(__func__); + *new_panel = {BLI_strdup(name), flag, ntree->next_panel_identifier++}; new_panels[new_panels.size() - 1] = new_panel; MEM_SAFE_FREE(old_panels_array); @@ -3851,18 +3849,17 @@ bNodeSocketPanel *ntreeAddSocketPanel(bNodeTree *ntree, const char *name, int fl return new_panel; } -bNodeSocketPanel *ntreeInsertSocketPanel(bNodeTree *ntree, const char *name, int flag, int index) +bNodePanel *ntreeInsertPanel(bNodeTree *ntree, const char *name, int flag, int index) { - if (!blender::IndexRange(ntree->socket_panels().size() + 1).contains(index)) { + if (!blender::IndexRange(ntree->panels().size() + 1).contains(index)) { return nullptr; } - bNodeSocketPanel **old_panels_array = ntree->socket_panels_array; - const Span old_panels = ntree->socket_panels(); - ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num + 1, - __func__); - ++ntree->socket_panels_num; - const MutableSpan new_panels = ntree->socket_panels_for_write(); + bNodePanel **old_panels_array = ntree->panels_array; + const Span old_panels = ntree->panels(); + ntree->panels_array = MEM_cnew_array(ntree->panels_num + 1, __func__); + ++ntree->panels_num; + const MutableSpan new_panels = ntree->panels_for_write(); Span old_panels_front = old_panels.take_front(index); Span old_panels_back = old_panels.drop_front(index); @@ -3870,8 +3867,8 @@ bNodeSocketPanel *ntreeInsertSocketPanel(bNodeTree *ntree, const char *name, int std::copy( old_panels_back.begin(), old_panels_back.end(), new_panels.drop_front(index + 1).data()); - bNodeSocketPanel *new_panel = MEM_cnew(__func__); - *new_panel = {BLI_strdup(name), flag, ntree->next_socket_panel_identifier++}; + bNodePanel *new_panel = MEM_cnew(__func__); + *new_panel = {BLI_strdup(name), flag, ntree->next_panel_identifier++}; new_panels[index] = new_panel; MEM_SAFE_FREE(old_panels_array); @@ -3881,9 +3878,9 @@ bNodeSocketPanel *ntreeInsertSocketPanel(bNodeTree *ntree, const char *name, int return new_panel; } -void ntreeRemoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel) +void ntreeRemovePanel(bNodeTree *ntree, bNodePanel *panel) { - const int index = ntreeGetSocketPanelIndex(ntree, panel); + const int index = ntreeGetPanelIndex(ntree, panel); if (index < 0) { return; } @@ -3900,12 +3897,11 @@ void ntreeRemoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel) } } - bNodeSocketPanel **old_panels_array = ntree->socket_panels_array; - const Span old_panels = ntree->socket_panels(); - ntree->socket_panels_array = MEM_cnew_array(ntree->socket_panels_num - 1, - __func__); - --ntree->socket_panels_num; - const MutableSpan new_panels = ntree->socket_panels_for_write(); + bNodePanel **old_panels_array = ntree->panels_array; + const Span old_panels = ntree->panels(); + ntree->panels_array = MEM_cnew_array(ntree->panels_num - 1, __func__); + --ntree->panels_num; + const MutableSpan new_panels = ntree->panels_for_write(); Span old_panels_front = old_panels.take_front(index); Span old_panels_back = old_panels.drop_front(index + 1); @@ -3919,7 +3915,7 @@ void ntreeRemoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel) ntreeEnsureSocketInterfacePanelOrder(ntree); } -void ntreeClearSocketPanels(bNodeTree *ntree) +void ntreeClearPanels(bNodeTree *ntree) { /* Remove references */ LISTBASE_FOREACH (bNodeSocket *, iosock, &ntree->inputs) { @@ -3929,38 +3925,37 @@ void ntreeClearSocketPanels(bNodeTree *ntree) iosock->panel = nullptr; } - for (bNodeSocketPanel *panel : ntree->socket_panels_for_write()) { + for (bNodePanel *panel : ntree->panels_for_write()) { MEM_SAFE_FREE(panel->name); MEM_SAFE_FREE(panel); } - MEM_SAFE_FREE(ntree->socket_panels_array); - ntree->socket_panels_array = nullptr; - ntree->socket_panels_num = 0; + MEM_SAFE_FREE(ntree->panels_array); + ntree->panels_array = nullptr; + ntree->panels_num = 0; /* No need to sort sockets, only null panel exists, relative order remains unchanged. */ } -void ntreeMoveSocketPanel(bNodeTree *ntree, bNodeSocketPanel *panel, int new_index) +void ntreeMovePanel(bNodeTree *ntree, bNodePanel *panel, int new_index) { - const int old_index = ntreeGetSocketPanelIndex(ntree, panel); + const int old_index = ntreeGetPanelIndex(ntree, panel); if (old_index < 0) { return; } - const MutableSpan panels = ntree->socket_panels_for_write(); + const MutableSpan panels = ntree->panels_for_write(); if (old_index == new_index) { return; } else if (old_index < new_index) { - const Span moved_panels = panels.slice(old_index + 1, - new_index - old_index); - bNodeSocketPanel *tmp = panels[old_index]; + const Span moved_panels = panels.slice(old_index + 1, new_index - old_index); + bNodePanel *tmp = panels[old_index]; std::copy(moved_panels.begin(), moved_panels.end(), panels.drop_front(old_index).data()); panels[new_index] = tmp; } else /* old_index > new_index */ { - const Span moved_panels = panels.slice(new_index, old_index - new_index); - bNodeSocketPanel *tmp = panels[old_index]; + const Span moved_panels = panels.slice(new_index, old_index - new_index); + bNodePanel *tmp = panels[old_index]; std::copy_backward( moved_panels.begin(), moved_panels.end(), panels.drop_front(old_index + 1).data()); panels[new_index] = tmp; diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 6ba7f262143..53d865c739d 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -169,7 +169,7 @@ typedef struct bNodeSocket { bNodeStack ns DNA_DEPRECATED; /* UI panel of the socket. */ - struct bNodeSocketPanel *panel; + struct bNodePanel *panel; bNodeSocketRuntimeHandle *runtime; @@ -534,11 +534,11 @@ typedef struct bNodeLink { #define NTREE_CHUNKSIZE_1024 1024 /** Panel in node tree for grouping sockets. */ -typedef struct bNodeSocketPanel { +typedef struct bNodePanel { char *name; int flag; int _pad; -} bNodeSocketPanel; +} bNodePanel; /* the basis for a Node tree, all links and nodes reside internal here */ /* only re-usable node trees are in the library though, @@ -603,11 +603,11 @@ typedef struct bNodeTree { /** Image representing what the node group does. */ struct PreviewImage *preview; - /* UI panels for sockets */ - struct bNodeSocketPanel **socket_panels_array; - int socket_panels_num; - int active_socket_panel; - int next_socket_panel_identifier; + /* UI panels */ + struct bNodePanel **panels_array; + int panels_num; + int active_panel; + int next_panel_identifier; char _pad2[4]; bNodeTreeRuntimeHandle *runtime; @@ -674,8 +674,8 @@ typedef struct bNodeTree { blender::Span interface_inputs() const; blender::Span interface_outputs() const; - blender::Span socket_panels() const; - blender::MutableSpan socket_panels_for_write(); + blender::Span panels() const; + blender::MutableSpan panels_for_write(); #endif } bNodeTree; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 70ef029d065..a1d4b648793 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3175,9 +3175,9 @@ static void rna_NodeSocketInterface_panel_set(PointerRNA *ptr, { bNodeSocket *socket = (bNodeSocket *)ptr->data; bNodeTree *ntree = (bNodeTree *)ptr->owner_id; - bNodeSocketPanel *panel = (bNodeSocketPanel *)value.data; + bNodePanel *panel = (bNodePanel *)value.data; - if (panel && !ntreeContainsSocketPanel(ntree, panel)) { + if (panel && !ntreeContainsPanel(ntree, panel)) { BKE_report(reports, RPT_ERROR, "Panel is not in the node tree interface"); return; } @@ -3188,9 +3188,9 @@ static void rna_NodeSocketInterface_panel_set(PointerRNA *ptr, static bool rna_NodeSocketInterface_panel_poll(PointerRNA *ptr, PointerRNA value) { bNodeTree *ntree = (bNodeTree *)ptr->owner_id; - bNodeSocketPanel *panel = (bNodeSocketPanel *)value.data; + bNodePanel *panel = (bNodePanel *)value.data; - return panel == NULL || ntreeContainsSocketPanel(ntree, panel); + return panel == NULL || ntreeContainsPanel(ntree, panel); } static void rna_NodeSocketInterface_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) @@ -3314,22 +3314,22 @@ static void rna_NodeSocketStandard_value_and_relation_update(struct bContext *C, /* ******** Node Socket Panels ******** */ -static void rna_NodeSocketPanel_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) +static void rna_NodePanel_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->owner_id; BKE_ntree_update_tag_interface(ntree); ED_node_tree_propagate_change(NULL, bmain, ntree); } -static bNodeSocketPanel *rna_NodeTree_socket_panels_new(bNodeTree *ntree, +static bNodePanel *rna_NodeTree_panels_new(bNodeTree *ntree, Main *bmain, ReportList *reports, const char *name) { - bNodeSocketPanel *panel = ntreeAddSocketPanel(ntree, name, 0); + bNodePanel *panel = ntreeAddPanel(ntree, name, 0); if (panel == NULL) { - BKE_report(reports, RPT_ERROR, "Unable to create socket panel"); + BKE_report(reports, RPT_ERROR, "Unable to create panel"); } else { BKE_ntree_update_tag_interface(ntree); @@ -3340,66 +3340,66 @@ static bNodeSocketPanel *rna_NodeTree_socket_panels_new(bNodeTree *ntree, return panel; } -static void rna_NodeTree_socket_panels_remove(bNodeTree *ntree, +static void rna_NodeTree_panels_remove(bNodeTree *ntree, Main *bmain, - bNodeSocketPanel *panel) + bNodePanel *panel) { - ntreeRemoveSocketPanel(ntree, panel); + ntreeRemovePanel(ntree, panel); BKE_ntree_update_tag_interface(ntree); ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } -static void rna_NodeTree_socket_panels_clear(bNodeTree *ntree, Main *bmain) +static void rna_NodeTree_panels_clear(bNodeTree *ntree, Main *bmain) { - ntreeClearSocketPanels(ntree); + ntreeClearPanels(ntree); BKE_ntree_update_tag_interface(ntree); ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } -static void rna_NodeTree_socket_panels_move(bNodeTree *ntree, +static void rna_NodeTree_panels_move(bNodeTree *ntree, Main *bmain, int from_index, int to_index) { - if (from_index < 0 || from_index >= ntree->socket_panels_num || to_index < 0 || - to_index >= ntree->socket_panels_num) + if (from_index < 0 || from_index >= ntree->panels_num || to_index < 0 || + to_index >= ntree->panels_num) { return; } - ntreeMoveSocketPanel(ntree, ntree->socket_panels_array[from_index], to_index); + ntreeMovePanel(ntree, ntree->panels_array[from_index], to_index); BKE_ntree_update_tag_interface(ntree); ED_node_tree_propagate_change(NULL, bmain, ntree); WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } -static PointerRNA rna_NodeTree_active_socket_panel_get(PointerRNA *ptr) +static PointerRNA rna_NodeTree_active_panel_get(PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->data; - bNodeSocketPanel *panel = NULL; - if (ntree->active_socket_panel >= 0 && - ntree->active_socket_panel < ntree->socket_panels_num) + bNodePanel *panel = NULL; + if (ntree->active_panel >= 0 && + ntree->active_panel < ntree->panels_num) { - panel = ntree->socket_panels_array[ntree->active_socket_panel]; + panel = ntree->panels_array[ntree->active_panel]; } PointerRNA r_ptr; - RNA_pointer_create(ptr->owner_id, &RNA_NodeSocketPanel, panel, &r_ptr); + RNA_pointer_create(ptr->owner_id, &RNA_NodePanel, panel, &r_ptr); return r_ptr; } -static void rna_NodeTree_active_socket_panel_set(PointerRNA *ptr, +static void rna_NodeTree_active_panel_set(PointerRNA *ptr, PointerRNA value, struct ReportList *UNUSED(reports)) { - bNodeSocketPanel *panel = (bNodeSocketPanel *)value.data; + bNodePanel *panel = (bNodePanel *)value.data; bNodeTree *ntree = (bNodeTree *)ptr->data; - ntree->active_socket_panel = ntreeGetSocketPanelIndex(ntree, panel); + ntree->active_panel = ntreeGetPanelIndex(ntree, panel); } /* ******** Node Types ******** */ @@ -11772,10 +11772,10 @@ static void rna_def_node_socket_interface(BlenderRNA *brna) "rna_NodeSocketInterface_panel_set", NULL, "rna_NodeSocketInterface_panel_poll"); - RNA_def_property_struct_type(prop, "NodeSocketPanel"); + RNA_def_property_struct_type(prop, "NodePanel"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text( - prop, "Socket Panel", "Panel to group sockets together in the UI"); + prop, "Panel", "Panel to group sockets together in the UI"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); prop = RNA_def_property(srna, "attribute_domain", PROP_ENUM, PROP_NONE); @@ -13051,16 +13051,16 @@ static void rna_def_node_socket_panel(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - srna = RNA_def_struct(brna, "NodeSocketPanel", NULL); - RNA_def_struct_ui_text(srna, "NodeSocketPanel", "Group of sockets in node tree interface"); - RNA_def_struct_sdna(srna, "bNodeSocketPanel"); + srna = RNA_def_struct(brna, "NodePanel", NULL); + RNA_def_struct_ui_text(srna, "NodePanel", "Panel in the node group interface"); + RNA_def_struct_sdna(srna, "bNodePanel"); RNA_def_struct_ui_icon(srna, ICON_NODE); prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_property_string_sdna(prop, NULL, "name"); RNA_def_property_ui_text(prop, "Name", "Name of the socket panel"); RNA_def_struct_name_property(srna, prop); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketPanel_update"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodePanel_update"); } static void rna_def_nodetree_nodes_api(BlenderRNA *brna, PropertyRNA *cprop) @@ -13209,50 +13209,50 @@ static void rna_def_node_tree_socket_panels_api(BlenderRNA *brna, PropertyRNA *c PropertyRNA *parm; FunctionRNA *func; - RNA_def_property_srna(cprop, "NodeSocketPanels"); - srna = RNA_def_struct(brna, "NodeSocketPanels", NULL); + RNA_def_property_srna(cprop, "NodePanels"); + srna = RNA_def_struct(brna, "NodePanels", NULL); RNA_def_struct_sdna(srna, "bNodeTree"); RNA_def_struct_ui_text( srna, "Node Tree Socket Panels", "Collection of socket panels in a node tree"); prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED); - RNA_def_property_int_sdna(prop, NULL, "active_socket_panel"); + RNA_def_property_int_sdna(prop, NULL, "active_panel"); RNA_def_property_ui_text(prop, "Active Index", "Index of the active panel"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_NODE, NULL); prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); - RNA_def_property_struct_type(prop, "NodeSocketPanel"); + RNA_def_property_struct_type(prop, "NodePanel"); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_pointer_funcs(prop, - "rna_NodeTree_active_socket_panel_get", - "rna_NodeTree_active_socket_panel_set", + "rna_NodeTree_active_panel_get", + "rna_NodeTree_active_panel_set", NULL, NULL); RNA_def_property_ui_text(prop, "Active", "Active panel"); RNA_def_property_update(prop, NC_NODE, NULL); - func = RNA_def_function(srna, "new", "rna_NodeTree_socket_panels_new"); - RNA_def_function_ui_description(func, "Add a new socket panel to the tree"); + func = RNA_def_function(srna, "new", "rna_NodeTree_panels_new"); + RNA_def_function_ui_description(func, "Add a new panel to the tree"); RNA_def_function_flag(func, FUNC_USE_MAIN | FUNC_USE_REPORTS); parm = RNA_def_string(func, "name", NULL, MAX_NAME, "Name", ""); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); /* return value */ - parm = RNA_def_pointer(func, "panel", "NodeSocketPanel", "", "New panel"); + parm = RNA_def_pointer(func, "panel", "NodePanel", "", "New panel"); RNA_def_function_return(func, parm); - func = RNA_def_function(srna, "remove", "rna_NodeTree_socket_panels_remove"); - RNA_def_function_ui_description(func, "Remove a socket panel from the tree"); + func = RNA_def_function(srna, "remove", "rna_NodeTree_panels_remove"); + RNA_def_function_ui_description(func, "Remove a panel from the tree"); RNA_def_function_flag(func, FUNC_USE_MAIN); - parm = RNA_def_pointer(func, "panel", "NodeSocketPanel", "", "The panel to remove"); + parm = RNA_def_pointer(func, "panel", "NodePanel", "", "The panel to remove"); RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); - func = RNA_def_function(srna, "clear", "rna_NodeTree_socket_panels_clear"); + func = RNA_def_function(srna, "clear", "rna_NodeTree_panels_clear"); RNA_def_function_ui_description(func, "Remove all panels from the tree"); RNA_def_function_flag(func, FUNC_USE_MAIN); - func = RNA_def_function(srna, "move", "rna_NodeTree_socket_panels_move"); - RNA_def_function_ui_description(func, "Move a socket panel to another position"); + func = RNA_def_function(srna, "move", "rna_NodeTree_panels_move"); + RNA_def_function_ui_description(func, "Move a panel to another position"); RNA_def_function_flag(func, FUNC_USE_MAIN); parm = RNA_def_int( func, "from_index", -1, 0, INT_MAX, "From Index", "Index of the panel to move", 0, 10000); @@ -13365,11 +13365,11 @@ static void rna_def_nodetree(BlenderRNA *brna) RNA_def_property_update(prop, NC_NODE, NULL); prop = RNA_def_property(srna, "socket_panels", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "socket_panels_array", "socket_panels_num"); - RNA_def_property_struct_type(prop, "NodeSocketPanel"); + RNA_def_property_collection_sdna(prop, NULL, "panels_array", "panels_num"); + RNA_def_property_struct_type(prop, "NodePanel"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text( - prop, "Socket Panels", "Socket panels for structuring the node tree interface"); + prop, "Panels", "UI panels for structuring the node tree interface"); rna_def_node_tree_socket_panels_api(brna, prop); /* exposed as a function for runtime interface type properties */ -- 2.30.2 From 63244d616da220549da2d60ac67cea367ee28d64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Fri, 9 Jun 2023 16:54:35 +0200 Subject: [PATCH 17/22] Cleanup: clang format. --- source/blender/makesrna/intern/rna_nodetree.c | 47 +++++++------------ 1 file changed, 16 insertions(+), 31 deletions(-) diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index a1d4b648793..4f95f1d4f77 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -3170,8 +3170,8 @@ static IDProperty **rna_NodeSocketInterface_idprops(PointerRNA *ptr) } static void rna_NodeSocketInterface_panel_set(PointerRNA *ptr, - PointerRNA value, - struct ReportList *reports) + PointerRNA value, + struct ReportList *reports) { bNodeSocket *socket = (bNodeSocket *)ptr->data; bNodeTree *ntree = (bNodeTree *)ptr->owner_id; @@ -3322,9 +3322,9 @@ static void rna_NodePanel_update(Main *bmain, Scene *UNUSED(scene), PointerRNA * } static bNodePanel *rna_NodeTree_panels_new(bNodeTree *ntree, - Main *bmain, - ReportList *reports, - const char *name) + Main *bmain, + ReportList *reports, + const char *name) { bNodePanel *panel = ntreeAddPanel(ntree, name, 0); @@ -3340,9 +3340,7 @@ static bNodePanel *rna_NodeTree_panels_new(bNodeTree *ntree, return panel; } -static void rna_NodeTree_panels_remove(bNodeTree *ntree, - Main *bmain, - bNodePanel *panel) +static void rna_NodeTree_panels_remove(bNodeTree *ntree, Main *bmain, bNodePanel *panel) { ntreeRemovePanel(ntree, panel); @@ -3360,10 +3358,7 @@ static void rna_NodeTree_panels_clear(bNodeTree *ntree, Main *bmain) WM_main_add_notifier(NC_NODE | NA_EDITED, ntree); } -static void rna_NodeTree_panels_move(bNodeTree *ntree, - Main *bmain, - int from_index, - int to_index) +static void rna_NodeTree_panels_move(bNodeTree *ntree, Main *bmain, int from_index, int to_index) { if (from_index < 0 || from_index >= ntree->panels_num || to_index < 0 || to_index >= ntree->panels_num) @@ -3382,9 +3377,7 @@ static PointerRNA rna_NodeTree_active_panel_get(PointerRNA *ptr) { bNodeTree *ntree = (bNodeTree *)ptr->data; bNodePanel *panel = NULL; - if (ntree->active_panel >= 0 && - ntree->active_panel < ntree->panels_num) - { + if (ntree->active_panel >= 0 && ntree->active_panel < ntree->panels_num) { panel = ntree->panels_array[ntree->active_panel]; } @@ -3394,8 +3387,8 @@ static PointerRNA rna_NodeTree_active_panel_get(PointerRNA *ptr) } static void rna_NodeTree_active_panel_set(PointerRNA *ptr, - PointerRNA value, - struct ReportList *UNUSED(reports)) + PointerRNA value, + struct ReportList *UNUSED(reports)) { bNodePanel *panel = (bNodePanel *)value.data; bNodeTree *ntree = (bNodeTree *)ptr->data; @@ -11767,15 +11760,11 @@ static void rna_def_node_socket_interface(BlenderRNA *brna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); prop = RNA_def_property(srna, "panel", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_funcs(prop, - NULL, - "rna_NodeSocketInterface_panel_set", - NULL, - "rna_NodeSocketInterface_panel_poll"); + RNA_def_property_pointer_funcs( + prop, NULL, "rna_NodeSocketInterface_panel_set", NULL, "rna_NodeSocketInterface_panel_poll"); RNA_def_property_struct_type(prop, "NodePanel"); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text( - prop, "Panel", "Panel to group sockets together in the UI"); + RNA_def_property_ui_text(prop, "Panel", "Panel to group sockets together in the UI"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); prop = RNA_def_property(srna, "attribute_domain", PROP_ENUM, PROP_NONE); @@ -13224,11 +13213,8 @@ static void rna_def_node_tree_socket_panels_api(BlenderRNA *brna, PropertyRNA *c prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "NodePanel"); RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_pointer_funcs(prop, - "rna_NodeTree_active_panel_get", - "rna_NodeTree_active_panel_set", - NULL, - NULL); + RNA_def_property_pointer_funcs( + prop, "rna_NodeTree_active_panel_get", "rna_NodeTree_active_panel_set", NULL, NULL); RNA_def_property_ui_text(prop, "Active", "Active panel"); RNA_def_property_update(prop, NC_NODE, NULL); @@ -13368,8 +13354,7 @@ static void rna_def_nodetree(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "panels_array", "panels_num"); RNA_def_property_struct_type(prop, "NodePanel"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text( - prop, "Panels", "UI panels for structuring the node tree interface"); + RNA_def_property_ui_text(prop, "Panels", "UI panels for structuring the node tree interface"); rna_def_node_tree_socket_panels_api(brna, prop); /* exposed as a function for runtime interface type properties */ -- 2.30.2 From 066d40b7b580976e79ee7de97211cd52bde8e744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Mon, 12 Jun 2023 10:49:51 +0200 Subject: [PATCH 18/22] Experimental flag to hide node panels and their effects for now. --- scripts/startup/bl_ui/space_node.py | 3 +++ scripts/startup/bl_ui/space_userpref.py | 1 + source/blender/blenkernel/intern/node.cc | 4 ++++ source/blender/editors/space_node/drawnode.cc | 4 +++- source/blender/makesdna/DNA_userdef_types.h | 3 ++- source/blender/makesrna/intern/rna_userdef.c | 4 ++++ 6 files changed, 17 insertions(+), 2 deletions(-) diff --git a/scripts/startup/bl_ui/space_node.py b/scripts/startup/bl_ui/space_node.py index d92a3cd5c2c..0cba232a2fc 100644 --- a/scripts/startup/bl_ui/space_node.py +++ b/scripts/startup/bl_ui/space_node.py @@ -974,6 +974,9 @@ class NODE_PT_socket_panels(Panel): @classmethod def poll(cls, context): + if not context.preferences.experimental.use_node_panels: + return False + snode = context.space_data if snode is None: return False diff --git a/scripts/startup/bl_ui/space_userpref.py b/scripts/startup/bl_ui/space_userpref.py index 00e82f83685..8bf033ecc7b 100644 --- a/scripts/startup/bl_ui/space_userpref.py +++ b/scripts/startup/bl_ui/space_userpref.py @@ -2410,6 +2410,7 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel): ("blender/blender/projects/10", "Pipeline, Assets & IO Project Page")), ({"property": "use_override_templates"}, ("blender/blender/issues/73318", "Milestone 4")), ({"property": "use_new_volume_nodes"}, ("blender/blender/issues/103248", "#103248")), + ({"property": "use_node_panels"}, ("blender/blender/issues/105248", "#105248")), ), ) diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index adeef5c7af9..fa4e042a4cd 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -3701,6 +3701,10 @@ bNodeSocket *ntreeFindSocketInterface(bNodeTree *ntree, void ntreeEnsureSocketInterfacePanelOrder(bNodeTree *ntree) { + if (!U.experimental.use_node_panels) { + return; + } + /* Store panel index for sorting. */ blender::Map panel_index_map; int index = 0; diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index 22d2fae601d..cb5cffe2f3a 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -1481,7 +1481,9 @@ static void std_node_socket_interface_draw(bContext * /*C*/, uiLayout *layout, P uiItemR(col, ptr, "hide_in_modifier", DEFAULT_FLAGS, nullptr, 0); } - uiItemPointerR(col, ptr, "panel", &tree_ptr, "socket_panels", nullptr, 0); + if (U.experimental.use_node_panels) { + uiItemPointerR(col, ptr, "socket_panel", &tree_ptr, "panels", nullptr, 0); + } } static void node_socket_virtual_draw_color(bContext * /*C*/, diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 68b88e2a47e..48bbb490b17 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -680,7 +680,8 @@ typedef struct UserDef_Experimental { char enable_overlay_next; char enable_workbench_next; char use_new_volume_nodes; - char _pad[4]; + char use_node_panels; + char _pad[3]; /** `makesdna` does not allow empty structs. */ } UserDef_Experimental; diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index ea0e960b047..e702a87fd73 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -6742,6 +6742,10 @@ static void rna_def_userdef_experimental(BlenderRNA *brna) prop = RNA_def_property(srna, "use_new_volume_nodes", PROP_BOOLEAN, PROP_NONE); RNA_def_property_ui_text( prop, "New Volume Nodes", "Enables visibility of the new Volume nodes in the UI"); + + prop = RNA_def_property(srna, "use_node_panels", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_ui_text( + prop, "Node Panels", "Enable node panels UI for grouping sockets in node groups"); } static void rna_def_userdef_addon_collection(BlenderRNA *brna, PropertyRNA *cprop) -- 2.30.2 From 26c1d070b5b38cd2ff5e42ee68dda3664c7c625c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Mon, 12 Jun 2023 10:52:03 +0200 Subject: [PATCH 19/22] Fix naming of "panel"/"panels" properties. --- source/blender/editors/space_node/drawnode.cc | 2 +- source/blender/makesrna/intern/rna_nodetree.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/space_node/drawnode.cc b/source/blender/editors/space_node/drawnode.cc index cb5cffe2f3a..6baf16caaa4 100644 --- a/source/blender/editors/space_node/drawnode.cc +++ b/source/blender/editors/space_node/drawnode.cc @@ -1482,7 +1482,7 @@ static void std_node_socket_interface_draw(bContext * /*C*/, uiLayout *layout, P } if (U.experimental.use_node_panels) { - uiItemPointerR(col, ptr, "socket_panel", &tree_ptr, "panels", nullptr, 0); + uiItemPointerR(col, ptr, "panel", &tree_ptr, "panels", nullptr, 0); } } diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 4f95f1d4f77..be035c36eda 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -13350,7 +13350,7 @@ static void rna_def_nodetree(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_NODE, NULL); - prop = RNA_def_property(srna, "socket_panels", PROP_COLLECTION, PROP_NONE); + prop = RNA_def_property(srna, "panels", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_sdna(prop, NULL, "panels_array", "panels_num"); RNA_def_property_struct_type(prop, "NodePanel"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); -- 2.30.2 From 5e1c8395c962140388bdadc1798cac228180b45d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Mon, 12 Jun 2023 11:53:16 +0200 Subject: [PATCH 20/22] Cleanup: Rename python classes to use "panel" instead "socket_panel". --- scripts/startup/bl_operators/node.py | 38 ++++++++++++++-------------- scripts/startup/bl_ui/space_node.py | 26 +++++++++---------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/scripts/startup/bl_operators/node.py b/scripts/startup/bl_operators/node.py index 06156e69006..b218f8562e4 100644 --- a/scripts/startup/bl_operators/node.py +++ b/scripts/startup/bl_operators/node.py @@ -244,7 +244,7 @@ class NODE_OT_tree_path_parent(Operator): return {'FINISHED'} -class NodeSocketPanelOperator(): +class NodePanelOperator(): @classmethod def poll(cls, context): snode = context.space_data @@ -258,16 +258,16 @@ class NodeSocketPanelOperator(): return True -class NODE_OT_socket_panel_add(NodeSocketPanelOperator, Operator): - '''Add a new socket panel to the tree''' - bl_idname = "node.socket_panel_add" - bl_label = "Add Socket Panel" +class NODE_OT_panel_add(NodePanelOperator, Operator): + '''Add a new panel to the tree''' + bl_idname = "node.panel_add" + bl_label = "Add Panel" bl_options = {'REGISTER', 'UNDO'} def execute(self, context): snode = context.space_data tree = snode.edit_tree - panels = tree.socket_panels + panels = tree.panels # Remember index to move the item. dst_index = min(panels.active_index + 1, len(panels)) @@ -278,16 +278,16 @@ class NODE_OT_socket_panel_add(NodeSocketPanelOperator, Operator): return {'FINISHED'} -class NODE_OT_socket_panel_remove(NodeSocketPanelOperator, Operator): - '''Remove a socket panel from the tree''' - bl_idname = "node.socket_panel_remove" - bl_label = "Remove Socket Panel" +class NODE_OT_panel_remove(NodePanelOperator, Operator): + '''Remove a panel from the tree''' + bl_idname = "node.panel_remove" + bl_label = "Remove Panel" bl_options = {'REGISTER', 'UNDO'} def execute(self, context): snode = context.space_data tree = snode.edit_tree - panels = tree.socket_panels + panels = tree.panels if panels.active: panels.remove(panels.active) @@ -296,10 +296,10 @@ class NODE_OT_socket_panel_remove(NodeSocketPanelOperator, Operator): return {'FINISHED'} -class NODE_OT_socket_panel_move(NodeSocketPanelOperator, Operator): - '''Move a socket panel to another position''' - bl_idname = "node.socket_panel_move" - bl_label = "Move Socket Panel" +class NODE_OT_panel_move(NodePanelOperator, Operator): + '''Move a panel to another position''' + bl_idname = "node.panel_move" + bl_label = "Move Panel" bl_options = {'REGISTER', 'UNDO'} direction: EnumProperty( @@ -311,7 +311,7 @@ class NODE_OT_socket_panel_move(NodeSocketPanelOperator, Operator): def execute(self, context): snode = context.space_data tree = snode.edit_tree - panels = tree.socket_panels + panels = tree.panels if self.direction == 'UP' and panels.active_index > 0: panels.move(panels.active_index, panels.active_index - 1) @@ -329,8 +329,8 @@ classes = ( NODE_OT_add_node, NODE_OT_add_simulation_zone, NODE_OT_collapse_hide_unused_toggle, - NODE_OT_socket_panel_add, - NODE_OT_socket_panel_remove, - NODE_OT_socket_panel_move, + NODE_OT_panel_add, + NODE_OT_panel_remove, + NODE_OT_panel_move, NODE_OT_tree_path_parent, ) diff --git a/scripts/startup/bl_ui/space_node.py b/scripts/startup/bl_ui/space_node.py index 0cba232a2fc..b5aa793f77e 100644 --- a/scripts/startup/bl_ui/space_node.py +++ b/scripts/startup/bl_ui/space_node.py @@ -960,17 +960,17 @@ class NODE_PT_node_tree_interface_outputs(NodeTreeInterfacePanel): self.draw_socket_list(context, "OUT", "outputs", "active_output") -class NODE_UL_socket_panels(bpy.types.UIList): +class NODE_UL_panels(bpy.types.UIList): def draw_item(self, context, layout, _data, item, icon, _active_data, _active_propname, _index): row = layout.row(align=True) row.prop(item, "name", text="", emboss=False, icon_value=icon) -class NODE_PT_socket_panels(Panel): +class NODE_PT_panels(Panel): bl_space_type = 'NODE_EDITOR' bl_region_type = 'UI' bl_category = "Group" - bl_label = "Socket Panels" + bl_label = "Node Panels" @classmethod def poll(cls, context): @@ -995,28 +995,28 @@ class NODE_PT_socket_panels(Panel): split = layout.row() split.template_list( - "NODE_UL_socket_panels", + "NODE_UL_panels", "", tree, - "socket_panels", - tree.socket_panels, + "panels", + tree.panels, "active_index") ops_col = split.column() add_remove_col = ops_col.column(align=True) - add_remove_col.operator("node.socket_panel_add", icon='ADD', text="") - add_remove_col.operator("node.socket_panel_remove", icon='REMOVE', text="") + add_remove_col.operator("node.panel_add", icon='ADD', text="") + add_remove_col.operator("node.panel_remove", icon='REMOVE', text="") ops_col.separator() up_down_col = ops_col.column(align=True) - props = up_down_col.operator("node.socket_panel_move", icon='TRIA_UP', text="") + props = up_down_col.operator("node.panel_move", icon='TRIA_UP', text="") props.direction = 'UP' - props = up_down_col.operator("node.socket_panel_move", icon='TRIA_DOWN', text="") + props = up_down_col.operator("node.panel_move", icon='TRIA_DOWN', text="") props.direction = 'DOWN' - active_panel = tree.socket_panels.active + active_panel = tree.panels.active if active_panel is not None: layout.prop(active_panel, "name") @@ -1164,8 +1164,8 @@ classes = ( NODE_UL_interface_sockets, NODE_PT_node_tree_interface_inputs, NODE_PT_node_tree_interface_outputs, - NODE_UL_socket_panels, - NODE_PT_socket_panels, + NODE_UL_panels, + NODE_PT_panels, NODE_UL_simulation_zone_items, NODE_PT_simulation_zone_items, -- 2.30.2 From ab52f3e5b1961b52447bface56d8e10a042e87a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Tue, 13 Jun 2023 12:41:08 +0200 Subject: [PATCH 21/22] Make panels() span accessor use const bNodePanel. --- source/blender/blenkernel/BKE_node_runtime.hh | 2 +- source/blender/blenkernel/intern/node.cc | 27 ++++++++++++------- source/blender/makesdna/DNA_node_types.h | 2 +- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/source/blender/blenkernel/BKE_node_runtime.hh b/source/blender/blenkernel/BKE_node_runtime.hh index d787c916965..1ef8e69bf71 100644 --- a/source/blender/blenkernel/BKE_node_runtime.hh +++ b/source/blender/blenkernel/BKE_node_runtime.hh @@ -516,7 +516,7 @@ inline blender::Span bNodeTree::root_frames() const return this->runtime->root_frames; } -inline blender::Span bNodeTree::panels() const +inline blender::Span bNodeTree::panels() const { return blender::Span(panels_array, panels_num); } diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index fa4e042a4cd..5b4f24b77e1 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -3835,12 +3835,14 @@ int ntreeGetPanelIndex(const bNodeTree *ntree, const bNodePanel *panel) bNodePanel *ntreeAddPanel(bNodeTree *ntree, const char *name, int flag) { bNodePanel **old_panels_array = ntree->panels_array; - const Span old_panels = ntree->panels(); + const Span old_panels = ntree->panels(); ntree->panels_array = MEM_cnew_array(ntree->panels_num + 1, __func__); ++ntree->panels_num; const MutableSpan new_panels = ntree->panels_for_write(); - std::copy(old_panels.begin(), old_panels.end(), new_panels.data()); + std::copy(const_cast(old_panels.begin()), + const_cast(old_panels.end()), + new_panels.data()); bNodePanel *new_panel = MEM_cnew(__func__); *new_panel = {BLI_strdup(name), flag, ntree->next_panel_identifier++}; @@ -3860,16 +3862,19 @@ bNodePanel *ntreeInsertPanel(bNodeTree *ntree, const char *name, int flag, int i } bNodePanel **old_panels_array = ntree->panels_array; - const Span old_panels = ntree->panels(); + const Span old_panels = ntree->panels(); ntree->panels_array = MEM_cnew_array(ntree->panels_num + 1, __func__); ++ntree->panels_num; const MutableSpan new_panels = ntree->panels_for_write(); Span old_panels_front = old_panels.take_front(index); Span old_panels_back = old_panels.drop_front(index); - std::copy(old_panels_front.begin(), old_panels_front.end(), new_panels.data()); - std::copy( - old_panels_back.begin(), old_panels_back.end(), new_panels.drop_front(index + 1).data()); + std::copy(const_cast(old_panels_front.begin()), + const_cast(old_panels_front.end()), + new_panels.data()); + std::copy(const_cast(old_panels_back.begin()), + const_cast(old_panels_back.end()), + new_panels.drop_front(index + 1).data()); bNodePanel *new_panel = MEM_cnew(__func__); *new_panel = {BLI_strdup(name), flag, ntree->next_panel_identifier++}; @@ -3902,15 +3907,19 @@ void ntreeRemovePanel(bNodeTree *ntree, bNodePanel *panel) } bNodePanel **old_panels_array = ntree->panels_array; - const Span old_panels = ntree->panels(); + const Span old_panels = ntree->panels(); ntree->panels_array = MEM_cnew_array(ntree->panels_num - 1, __func__); --ntree->panels_num; const MutableSpan new_panels = ntree->panels_for_write(); Span old_panels_front = old_panels.take_front(index); Span old_panels_back = old_panels.drop_front(index + 1); - std::copy(old_panels_front.begin(), old_panels_front.end(), new_panels.data()); - std::copy(old_panels_back.begin(), old_panels_back.end(), new_panels.drop_front(index).data()); + std::copy(const_cast(old_panels_front.begin()), + const_cast(old_panels_front.end()), + new_panels.data()); + std::copy(const_cast(old_panels_back.begin()), + const_cast(old_panels_back.end()), + new_panels.drop_front(index).data()); MEM_SAFE_FREE(panel->name); MEM_SAFE_FREE(panel); diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h index 53d865c739d..a50c6415b96 100644 --- a/source/blender/makesdna/DNA_node_types.h +++ b/source/blender/makesdna/DNA_node_types.h @@ -674,7 +674,7 @@ typedef struct bNodeTree { blender::Span interface_inputs() const; blender::Span interface_outputs() const; - blender::Span panels() const; + blender::Span panels() const; blender::MutableSpan panels_for_write(); #endif } bNodeTree; -- 2.30.2 From e66992a7b27802e525c55fa7ea7c7323531a04e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Tue, 13 Jun 2023 12:41:44 +0200 Subject: [PATCH 22/22] Replace Map with VectorSet for cleaner sorting code. --- source/blender/blenkernel/intern/node.cc | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 5b4f24b77e1..6dda81d92db 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -3671,15 +3671,15 @@ static bNodeSocket *make_socket_interface(bNodeTree *ntree, return sock; } -using PanelIndexMap = blender::Map; +using PanelIndexMap = blender::VectorSet; static int node_socket_panel_cmp(void *panel_index_map_v, const void *a, const void *b) { const PanelIndexMap &panel_index_map = *static_cast(panel_index_map_v); const bNodeSocket *sock_a = static_cast(a); const bNodeSocket *sock_b = static_cast(b); - return panel_index_map.lookup_default(sock_a->panel, -1) > - panel_index_map.lookup_default(sock_b->panel, -1) ? + return panel_index_map.index_of_try(sock_a->panel) > + panel_index_map.index_of_try(sock_b->panel) ? 1 : 0; } @@ -3706,11 +3706,7 @@ void ntreeEnsureSocketInterfacePanelOrder(bNodeTree *ntree) } /* Store panel index for sorting. */ - blender::Map panel_index_map; - int index = 0; - for (const bNodePanel *panel : ntree->panels()) { - panel_index_map.add_new(panel, index++); - } + blender::bke::PanelIndexMap panel_index_map(ntree->panels()); BLI_listbase_sort_r(&ntree->inputs, blender::bke::node_socket_panel_cmp, &panel_index_map); BLI_listbase_sort_r(&ntree->outputs, blender::bke::node_socket_panel_cmp, &panel_index_map); } -- 2.30.2