diff --git a/source/blender/editors/interface/templates/interface_template_node_inputs.cc b/source/blender/editors/interface/templates/interface_template_node_inputs.cc index 209412a2122..4699f8eeaf1 100644 --- a/source/blender/editors/interface/templates/interface_template_node_inputs.cc +++ b/source/blender/editors/interface/templates/interface_template_node_inputs.cc @@ -97,7 +97,7 @@ static void handle_node_declaration_items(bContext *C, else if (const PanelDeclaration *panel_decl = dynamic_cast( item_decl)) { - const ItemIterator panel_item_end = item_iter + panel_decl->num_child_decls; + const ItemIterator panel_item_end = item_iter + panel_decl->items.size(); BLI_assert(panel_item_end <= item_end); /* Use a root panel property to toggle open/closed state. */ @@ -138,8 +138,8 @@ void uiTemplateNodeInputs(uiLayout *layout, bContext *C, PointerRNA *ptr) if (node.declaration()) { /* Draw socket inputs and panel buttons in the order of declaration panels. */ - ItemIterator item_iter = node.declaration()->items.begin(); - const ItemIterator item_end = node.declaration()->items.end(); + ItemIterator item_iter = node.declaration()->all_items.begin(); + const ItemIterator item_end = node.declaration()->all_items.end(); Panel *root_panel = uiLayoutGetRootPanel(layout); blender::ui::nodes::handle_node_declaration_items( C, root_panel, layout, ptr, item_iter, item_end); diff --git a/source/blender/editors/space_node/node_draw.cc b/source/blender/editors/space_node/node_draw.cc index b3ace4d5a2e..29bf2be0c4c 100644 --- a/source/blender/editors/space_node/node_draw.cc +++ b/source/blender/editors/space_node/node_draw.cc @@ -622,12 +622,12 @@ static Vector node_build_item_data(bNode &node) BLI_assert(is_node_panels_supported(node)); BLI_assert(node.runtime->panels.size() == node.num_panel_states); - ItemDeclIterator item_decl = node.declaration()->items.begin(); + ItemDeclIterator item_decl = node.declaration()->all_items.begin(); SocketIterator input = node.input_sockets().begin(); SocketIterator output = node.output_sockets().begin(); PanelStateIterator panel_state = node.panel_states().begin(); PanelRuntimeIterator panel_runtime = node.runtime->panels.begin(); - const ItemDeclIterator item_decl_end = node.declaration()->items.end(); + const ItemDeclIterator item_decl_end = node.declaration()->all_items.end(); const SocketIterator input_end = node.input_sockets().end(); const SocketIterator output_end = node.output_sockets().end(); const PanelStateIterator panel_state_end = node.panel_states().end(); @@ -635,7 +635,7 @@ static Vector node_build_item_data(bNode &node) UNUSED_VARS_NDEBUG(input_end, output_end, panel_state_end, panel_runtime_end); Vector result; - result.reserve(node.declaration()->items.size()); + result.reserve(node.declaration()->all_items.size()); while (item_decl != item_decl_end) { if (const nodes::SocketDeclaration *socket_decl = @@ -729,7 +729,7 @@ static void node_update_panel_items_visibility_recursive(int num_items, const bool is_collapsed = is_parent_collapsed || item.state->is_collapsed(); node_update_panel_items_visibility_recursive( - item.panel_decl->num_child_decls, is_collapsed, *item.state, state); + item.panel_decl->items.size(), is_collapsed, *item.state, state); if (item.panel_decl->draw_buttons) { item.state->flag |= NODE_PANEL_CONTENT_VISIBLE; } @@ -842,7 +842,7 @@ static void add_panel_items_recursive(const bContext &C, block, locx, locy, - item.panel_decl->num_child_decls, + item.panel_decl->items.size(), is_collapsed, item.panel_decl->name.c_str(), item.runtime, @@ -2477,7 +2477,7 @@ static void node_draw_panels_background(const bNode &node, uiBlock &block) float last_panel_content_y = 0.0f; int panel_i = 0; - for (const nodes::ItemDeclarationPtr &item_decl : decl.items) { + for (const nodes::ItemDeclarationPtr &item_decl : decl.all_items) { const nodes::PanelDeclaration *panel_decl = dynamic_cast( item_decl.get()); if (panel_decl == nullptr) { @@ -2533,7 +2533,7 @@ static void node_draw_panels(bNodeTree &ntree, const bNode &node, uiBlock &block const rctf &rct = node.runtime->totr; int panel_i = 0; - for (const nodes::ItemDeclarationPtr &item_decl : decl.items) { + for (const nodes::ItemDeclarationPtr &item_decl : decl.all_items) { const nodes::PanelDeclaration *panel_decl = dynamic_cast( item_decl.get()); if (panel_decl == nullptr) { diff --git a/source/blender/editors/space_node/node_templates.cc b/source/blender/editors/space_node/node_templates.cc index 0446d22dc93..bb98a9d2434 100644 --- a/source/blender/editors/space_node/node_templates.cc +++ b/source/blender/editors/space_node/node_templates.cc @@ -811,10 +811,10 @@ static void ui_node_draw_node( using SocketIterator = blender::Span::iterator; using PanelStateIterator = blender::MutableSpan::iterator; - ItemDeclIterator item_decl = node.declaration()->items.begin(); + ItemDeclIterator item_decl = node.declaration()->all_items.begin(); SocketIterator input = node.input_sockets().begin(); PanelStateIterator panel_state = node.panel_states().begin(); - const ItemDeclIterator item_decl_end = node.declaration()->items.end(); + const ItemDeclIterator item_decl_end = node.declaration()->all_items.end(); bool panel_collapsed = false; const char *panel_label = nullptr; diff --git a/source/blender/nodes/NOD_node_declaration.hh b/source/blender/nodes/NOD_node_declaration.hh index bc1df943a57..c71d4f813a8 100644 --- a/source/blender/nodes/NOD_node_declaration.hh +++ b/source/blender/nodes/NOD_node_declaration.hh @@ -252,6 +252,8 @@ class SocketDeclaration : public ItemDeclaration { }; class NodeDeclarationBuilder; +class DeclarationListBuilder; +class PanelDeclarationBuilder; class BaseSocketDeclarationBuilder { protected: @@ -264,6 +266,7 @@ class BaseSocketDeclarationBuilder { SocketDeclaration *decl_base_ = nullptr; friend class NodeDeclarationBuilder; + friend class DeclarationListBuilder; public: virtual ~BaseSocketDeclarationBuilder() = default; @@ -274,6 +277,8 @@ class BaseSocketDeclarationBuilder { BaseSocketDeclarationBuilder &multi_input(bool value = true); + BaseSocketDeclarationBuilder &compact(bool value = true); + BaseSocketDeclarationBuilder &short_label(std::string value = ""); BaseSocketDeclarationBuilder &description(std::string value = ""); @@ -404,6 +409,7 @@ class SocketDeclarationBuilder : public BaseSocketDeclarationBuilder { SocketDecl *decl_; friend class NodeDeclarationBuilder; + friend class DeclarationListBuilder; }; using SocketDeclarationPtr = std::unique_ptr; @@ -422,8 +428,8 @@ class PanelDeclaration : public ItemDeclaration { std::string description; std::string translation_context; bool default_collapsed = false; - int num_child_decls = 0; PanelDrawButtonsFunction draw_buttons = nullptr; + Vector items; private: friend NodeDeclarationBuilder; @@ -437,23 +443,25 @@ class PanelDeclaration : public ItemDeclaration { void update_or_build(const bNodePanelState &old_panel, bNodePanelState &new_panel) const; }; -class PanelDeclarationBuilder { - protected: - using Self = PanelDeclarationBuilder; - NodeDeclarationBuilder *node_decl_builder_ = nullptr; - PanelDeclaration *decl_; - /** - * Panel is complete once items are added after it. - * Completed panels are locked and no more items can be added. - */ - bool is_complete_ = false; - - friend class NodeDeclarationBuilder; - +/** + * This is a base class for #NodeDeclarationBuilder and #PanelDeclarationBuilder. It unifies the + * behavior of adding sockets and other items to the root node and to panels. + */ +class DeclarationListBuilder { public: - Self &description(std::string value = ""); - Self &default_closed(bool closed); - Self &draw_buttons(PanelDrawButtonsFunction func); + NodeDeclarationBuilder &node_decl_builder; + Vector &items; + + DeclarationListBuilder(NodeDeclarationBuilder &node_decl_builder, + Vector &items) + : node_decl_builder(node_decl_builder), items(items) + { + } + + template + typename DeclType::Builder &add_socket(StringRef name, + StringRef identifier, + eNodeSocketInOut in_out); template typename DeclType::Builder &add_input(StringRef name, StringRef identifier = ""); @@ -473,17 +481,38 @@ class PanelDeclarationBuilder { StringRef name, StringRef identifier = ""); + PanelDeclarationBuilder &add_panel(StringRef name, int identifier = -1); + void add_separator(); }; +class PanelDeclarationBuilder : public DeclarationListBuilder { + protected: + using Self = PanelDeclarationBuilder; + PanelDeclaration *decl_; + + friend class NodeDeclarationBuilder; + + public: + PanelDeclarationBuilder(NodeDeclarationBuilder &node_builder, PanelDeclaration &decl) + : DeclarationListBuilder(node_builder, decl.items), decl_(&decl) + { + } + + Self &description(std::string value = ""); + Self &default_closed(bool closed); + Self &draw_buttons(PanelDrawButtonsFunction func); +}; + using PanelDeclarationPtr = std::unique_ptr; class NodeDeclaration { public: - /* Combined list of socket and panel declarations. - * This determines order of sockets in the UI and panel content. */ - Vector items; - /* NOTE: inputs and outputs pointers are owned by the items list. */ + /* Contains all items including recursive children.*/ + Vector all_items; + /* Contains only the items in the root. */ + Vector root_items; + /* All input and output socket declarations. */ Vector inputs; Vector outputs; std::unique_ptr anonymous_attribute_relations_; @@ -508,8 +537,8 @@ class NodeDeclaration { friend NodeDeclarationBuilder; - /** Returns true if the declaration is considered valid. */ - bool is_valid() const; + /** Asserts that the declaration is considered valid. */ + void assert_valid() const; bool matches(const bNode &node) const; Span sockets(eNodeSocketInOut in_out) const; @@ -522,7 +551,7 @@ class NodeDeclaration { MEM_CXX_CLASS_ALLOC_FUNCS("NodeDeclaration") }; -class NodeDeclarationBuilder { +class NodeDeclarationBuilder : public DeclarationListBuilder { private: NodeDeclaration &declaration_; const bNodeTree *ntree_ = nullptr; @@ -534,7 +563,7 @@ class NodeDeclarationBuilder { bool is_function_node_ = false; private: - friend PanelDeclarationBuilder; + friend DeclarationListBuilder; public: NodeDeclarationBuilder(NodeDeclaration &declaration, @@ -567,27 +596,6 @@ class NodeDeclarationBuilder { void use_custom_socket_order(bool enable = true); void allow_any_socket_order(bool enable = true); - template - typename DeclType::Builder &add_input(StringRef name, StringRef identifier = ""); - template - typename DeclType::Builder &add_output(StringRef name, StringRef identifier = ""); - PanelDeclarationBuilder &add_panel(StringRef name, int identifier = -1); - - BaseSocketDeclarationBuilder &add_input(eNodeSocketDatatype socket_type, - StringRef name, - StringRef identifier = ""); - BaseSocketDeclarationBuilder &add_input(eCustomDataType data_type, - StringRef name, - StringRef identifier = ""); - BaseSocketDeclarationBuilder &add_output(eNodeSocketDatatype socket_type, - StringRef name, - StringRef identifier = ""); - BaseSocketDeclarationBuilder &add_output(eCustomDataType data_type, - StringRef name, - StringRef identifier = ""); - - void add_separator(); - aal::RelationsInNode &get_anonymous_attribute_relations() { if (!declaration_.anonymous_attribute_relations_) { @@ -602,16 +610,6 @@ class NodeDeclarationBuilder { } private: - template - typename DeclType::Builder &add_socket(StringRef name, - StringRef identifier_in, - StringRef identifier_out, - eNodeSocketInOut in_out); - - /* Mark the most recent builder as 'complete' when changing builders - * so no more items can be added. */ - void set_active_panel_builder(const PanelDeclarationBuilder *panel_builder); - void build_remaining_anonymous_attribute_relations(); }; @@ -632,33 +630,71 @@ std::unique_ptr make_declaration_for_socket_type( eNodeSocketDatatype socket_type); /* -------------------------------------------------------------------- */ -/** \name #PanelDeclarationBuilder Inline Methods +/** \name #DeclarationListBuilder Inline Methods * \{ */ template -typename DeclType::Builder &PanelDeclarationBuilder::add_input(StringRef name, - StringRef identifier) +inline typename DeclType::Builder &DeclarationListBuilder::add_input(StringRef name, + StringRef identifier) { - if (is_complete_) { - static typename DeclType::Builder dummy_builder = {}; - BLI_assert_unreachable(); - return dummy_builder; - } - ++this->decl_->num_child_decls; - return node_decl_builder_->add_socket(name, identifier, "", SOCK_IN); + return this->add_socket(name, identifier, SOCK_IN); } template -typename DeclType::Builder &PanelDeclarationBuilder::add_output(StringRef name, - StringRef identifier) +inline typename DeclType::Builder &DeclarationListBuilder::add_output(StringRef name, + StringRef identifier) { - if (is_complete_) { - static typename DeclType::Builder dummy_builder = {}; - BLI_assert_unreachable(); - return dummy_builder; + return this->add_socket(name, identifier, SOCK_OUT); +} + +template +inline typename DeclType::Builder &DeclarationListBuilder::add_socket(StringRef name, + StringRef identifier, + eNodeSocketInOut in_out) +{ + static_assert(std::is_base_of_v); + using SocketBuilder = typename DeclType::Builder; + + BLI_assert(ELEM(in_out, SOCK_IN, SOCK_OUT)); + + std::unique_ptr socket_decl_builder_ptr = std::make_unique(); + SocketBuilder &socket_decl_builder = *socket_decl_builder_ptr; + this->node_decl_builder.socket_builders_.append(std::move(socket_decl_builder_ptr)); + + std::unique_ptr socket_decl_ptr = std::make_unique(); + DeclType &socket_decl = *socket_decl_ptr; + this->node_decl_builder.declaration_.all_items.append(std::move(socket_decl_ptr)); + this->items.append(&socket_decl); + + socket_decl_builder.node_decl_builder_ = &this->node_decl_builder; + + socket_decl_builder.decl_ = &socket_decl; + socket_decl_builder.decl_base_ = &socket_decl; + socket_decl.name = name; + socket_decl.identifier = identifier.is_empty() ? name : identifier; + socket_decl.in_out = in_out; + socket_decl.socket_type = DeclType::static_socket_type; + + if (this->node_decl_builder.is_function_node_) { + if (in_out == SOCK_IN) { + socket_decl_builder.supports_field(); + } + else { + socket_decl_builder.dependent_field(); + } } - ++this->decl_->num_child_decls; - return node_decl_builder_->add_socket(name, "", identifier, SOCK_OUT); + + if (in_out == SOCK_IN) { + this->node_decl_builder.input_socket_builders_.append(&socket_decl_builder); + socket_decl_builder.index_ = this->node_decl_builder.declaration_.inputs.append_and_get_index( + &socket_decl); + } + else { + this->node_decl_builder.output_socket_builders_.append(&socket_decl_builder); + socket_decl_builder.index_ = this->node_decl_builder.declaration_.outputs.append_and_get_index( + &socket_decl); + } + return socket_decl_builder; } /** \} */ @@ -684,80 +720,4 @@ inline bool BaseSocketDeclarationBuilder::is_output() const /** \} */ -/* -------------------------------------------------------------------- */ -/** \name #NodeDeclarationBuilder Inline Methods - * \{ */ - -template -inline typename DeclType::Builder &NodeDeclarationBuilder::add_input(StringRef name, - StringRef identifier) -{ - set_active_panel_builder(nullptr); - return this->add_socket(name, identifier, "", SOCK_IN); -} - -template -inline typename DeclType::Builder &NodeDeclarationBuilder::add_output(StringRef name, - StringRef identifier) -{ - set_active_panel_builder(nullptr); - return this->add_socket(name, "", identifier, SOCK_OUT); -} - -template -inline typename DeclType::Builder &NodeDeclarationBuilder::add_socket(StringRef name, - StringRef identifier_in, - StringRef identifier_out, - eNodeSocketInOut in_out) -{ - static_assert(std::is_base_of_v); - using Builder = typename DeclType::Builder; - - BLI_assert(ELEM(in_out, SOCK_IN, SOCK_OUT)); - - std::unique_ptr socket_decl_builder = std::make_unique(); - socket_decl_builder->node_decl_builder_ = this; - - if (in_out & SOCK_IN) { - std::unique_ptr socket_decl = std::make_unique(); - socket_decl_builder->decl_ = &*socket_decl; - socket_decl_builder->decl_base_ = &*socket_decl; - socket_decl->name = name; - socket_decl->identifier = identifier_in.is_empty() ? name : identifier_in; - socket_decl->in_out = SOCK_IN; - socket_decl->socket_type = DeclType::static_socket_type; - socket_decl_builder->index_ = declaration_.inputs.append_and_get_index(socket_decl.get()); - declaration_.items.append(std::move(socket_decl)); - input_socket_builders_.append(&*socket_decl_builder); - } - if (in_out & SOCK_OUT) { - std::unique_ptr socket_decl = std::make_unique(); - socket_decl_builder->decl_ = &*socket_decl; - socket_decl_builder->decl_base_ = &*socket_decl; - socket_decl->name = name; - socket_decl->identifier = identifier_out.is_empty() ? name : identifier_out; - socket_decl->in_out = SOCK_OUT; - socket_decl->socket_type = DeclType::static_socket_type; - socket_decl_builder->index_ = declaration_.outputs.append_and_get_index(socket_decl.get()); - declaration_.items.append(std::move(socket_decl)); - output_socket_builders_.append(&*socket_decl_builder); - } - - if (is_function_node_) { - if (in_out == SOCK_IN) { - socket_decl_builder->supports_field(); - } - else { - socket_decl_builder->dependent_field(); - } - } - - Builder &socket_decl_builder_ref = *socket_decl_builder; - socket_builders_.append(std::move(socket_decl_builder)); - - return socket_decl_builder_ref; -} - -/** \} */ - } // namespace blender::nodes diff --git a/source/blender/nodes/NOD_socket_declarations.hh b/source/blender/nodes/NOD_socket_declarations.hh index c76eb31a40f..928ee111790 100644 --- a/source/blender/nodes/NOD_socket_declarations.hh +++ b/source/blender/nodes/NOD_socket_declarations.hh @@ -255,11 +255,20 @@ class IDSocketDeclaration : public SocketDeclaration { bool can_connect(const bNodeSocket &socket) const override; }; +template class IDSocketDeclarationBuilder : public SocketDeclarationBuilder { + public: + IDSocketDeclarationBuilder &default_value_fn(std::function fn) + { + this->decl_->default_value_fn = std::move(fn); + return *this; + } +}; + class Object : public IDSocketDeclaration { public: static constexpr eNodeSocketDatatype static_socket_type = SOCK_OBJECT; - using Builder = SocketDeclarationBuilder; + using Builder = IDSocketDeclarationBuilder; Object(); }; @@ -268,7 +277,7 @@ class Material : public IDSocketDeclaration { public: static constexpr eNodeSocketDatatype static_socket_type = SOCK_MATERIAL; - using Builder = SocketDeclarationBuilder; + using Builder = IDSocketDeclarationBuilder; Material(); }; @@ -277,7 +286,7 @@ class Collection : public IDSocketDeclaration { public: static constexpr eNodeSocketDatatype static_socket_type = SOCK_COLLECTION; - using Builder = SocketDeclarationBuilder; + using Builder = IDSocketDeclarationBuilder; Collection(); }; @@ -286,7 +295,7 @@ class Texture : public IDSocketDeclaration { public: static constexpr eNodeSocketDatatype static_socket_type = SOCK_TEXTURE; - using Builder = SocketDeclarationBuilder; + using Builder = IDSocketDeclarationBuilder; Texture(); }; @@ -295,7 +304,7 @@ class Image : public IDSocketDeclaration { public: static constexpr eNodeSocketDatatype static_socket_type = SOCK_IMAGE; - using Builder = SocketDeclarationBuilder; + using Builder = IDSocketDeclarationBuilder; Image(); }; @@ -358,6 +367,13 @@ class Custom : public SocketDeclaration { class CustomTypeBuilder : public SocketDeclarationBuilder { public: CustomTypeBuilder &idname(const char *idname); + + CustomTypeBuilder &init_socket_fn( + std::function fn) + { + decl_->init_socket_fn = std::move(fn); + return *this; + } }; /* -------------------------------------------------------------------- */ @@ -552,6 +568,4 @@ inline CustomTypeBuilder &CustomTypeBuilder::idname(const char *idname) /** \} */ -SocketDeclarationPtr create_extend_declaration(const eNodeSocketInOut in_out); - } // namespace blender::nodes::decl diff --git a/source/blender/nodes/intern/node_common.cc b/source/blender/nodes/intern/node_common.cc index 1363a3d610b..b6d182d3c22 100644 --- a/source/blender/nodes/intern/node_common.cc +++ b/source/blender/nodes/intern/node_common.cc @@ -239,196 +239,132 @@ get_init_socket_fn(const bNodeTreeInterface &interface, const bNodeTreeInterface }; } -/* in_out overrides the socket declaration in/out type (bNodeTreeInterfaceSocket::flag) - * because a node group input is turned into an output socket for group input nodes. */ -static SocketDeclarationPtr declaration_for_interface_socket( - const bNodeTree &ntree, +static BaseSocketDeclarationBuilder &build_interface_socket_declaration( + const bNodeTree &tree, const bNodeTreeInterfaceSocket &io_socket, - const eNodeSocketInOut in_out) + const eNodeSocketInOut in_out, + DeclarationListBuilder &b) { - SocketDeclarationPtr dst; - blender::bke::bNodeSocketType *base_typeinfo = blender::bke::node_socket_type_find( io_socket.socket_type); eNodeSocketDatatype datatype = SOCK_CUSTOM; + + const StringRef name = io_socket.name; + const StringRef identifier = io_socket.identifier; + + BaseSocketDeclarationBuilder *decl = nullptr; if (base_typeinfo) { datatype = eNodeSocketDatatype(base_typeinfo->type); switch (datatype) { case SOCK_FLOAT: { const auto &value = node_interface::get_socket_data_as(io_socket); - std::unique_ptr decl = std::make_unique(); - decl->subtype = PropertySubType(value.subtype); - decl->default_value = value.value; - decl->soft_min_value = value.min; - decl->soft_max_value = value.max; - dst = std::move(decl); + decl = &b.add_socket(name, identifier, in_out) + .subtype(PropertySubType(value.subtype)) + .default_value(value.value) + .min(value.min) + .max(value.max); break; } case SOCK_VECTOR: { const auto &value = node_interface::get_socket_data_as(io_socket); - std::unique_ptr decl = std::make_unique(); - decl->subtype = PropertySubType(value.subtype); - decl->default_value = value.value; - decl->soft_min_value = value.min; - decl->soft_max_value = value.max; - dst = std::move(decl); + decl = &b.add_socket(name, identifier, in_out) + .subtype(PropertySubType(value.subtype)) + .default_value(value.value) + .min(value.min) + .max(value.max); break; } case SOCK_RGBA: { const auto &value = node_interface::get_socket_data_as(io_socket); - std::unique_ptr decl = std::make_unique(); - decl->default_value = value.value; - dst = std::move(decl); + decl = &b.add_socket(name, identifier, in_out).default_value(value.value); break; } case SOCK_SHADER: { - std::unique_ptr decl = std::make_unique(); - dst = std::move(decl); + decl = &b.add_socket(name, identifier, in_out); break; } case SOCK_BOOLEAN: { const auto &value = node_interface::get_socket_data_as(io_socket); - std::unique_ptr decl = std::make_unique(); - decl->default_value = value.value; - dst = std::move(decl); + decl = &b.add_socket(name, identifier, in_out).default_value(value.value); break; } case SOCK_ROTATION: { const auto &value = node_interface::get_socket_data_as( io_socket); - std::unique_ptr decl = std::make_unique(); - decl->default_value = math::EulerXYZ(float3(value.value_euler)); - dst = std::move(decl); + decl = &b.add_socket(name, identifier, in_out) + .default_value(math::EulerXYZ(float3(value.value_euler))); break; } case SOCK_MATRIX: { - std::unique_ptr decl = std::make_unique(); - dst = std::move(decl); + decl = &b.add_socket(name, identifier, in_out); break; } case SOCK_INT: { const auto &value = node_interface::get_socket_data_as(io_socket); - std::unique_ptr decl = std::make_unique(); - decl->subtype = PropertySubType(value.subtype); - decl->default_value = value.value; - decl->soft_min_value = value.min; - decl->soft_max_value = value.max; - dst = std::move(decl); + decl = &b.add_socket(name, identifier, in_out) + .subtype(PropertySubType(value.subtype)) + .default_value(value.value) + .min(value.min) + .max(value.max); break; } case SOCK_STRING: { const auto &value = node_interface::get_socket_data_as(io_socket); - std::unique_ptr decl = std::make_unique(); - decl->default_value = value.value; - decl->subtype = PropertySubType(value.subtype); - dst = std::move(decl); + decl = &b.add_socket(name, identifier, in_out) + .subtype(PropertySubType(value.subtype)) + .default_value(value.value); break; } case SOCK_MENU: { const auto &value = node_interface::get_socket_data_as(io_socket); - std::unique_ptr decl = std::make_unique(); - decl->default_value = value.value; - dst = std::move(decl); + decl = &b.add_socket(name, identifier, in_out).default_value(value.value); break; } case SOCK_OBJECT: { - auto value = std::make_unique(); - value->default_value_fn = get_default_id_getter(ntree.tree_interface, io_socket); - dst = std::move(value); + decl = &b.add_socket(name, identifier, in_out) + .default_value_fn(get_default_id_getter(tree.tree_interface, io_socket)); break; } case SOCK_IMAGE: { - auto value = std::make_unique(); - value->default_value_fn = get_default_id_getter(ntree.tree_interface, io_socket); - dst = std::move(value); + decl = &b.add_socket(name, identifier, in_out) + .default_value_fn(get_default_id_getter(tree.tree_interface, io_socket)); break; } case SOCK_GEOMETRY: - dst = std::make_unique(); + decl = &b.add_socket(name, identifier, in_out); break; case SOCK_COLLECTION: { - auto value = std::make_unique(); - value->default_value_fn = get_default_id_getter(ntree.tree_interface, io_socket); - dst = std::move(value); + decl = &b.add_socket(name, identifier, in_out) + .default_value_fn(get_default_id_getter(tree.tree_interface, io_socket)); break; } case SOCK_TEXTURE: { - auto value = std::make_unique(); - value->default_value_fn = get_default_id_getter(ntree.tree_interface, io_socket); - dst = std::move(value); + decl = &b.add_socket(name, identifier, in_out) + .default_value_fn(get_default_id_getter(tree.tree_interface, io_socket)); break; } case SOCK_MATERIAL: { - auto value = std::make_unique(); - value->default_value_fn = get_default_id_getter(ntree.tree_interface, io_socket); - dst = std::move(value); + decl = &b.add_socket(name, identifier, in_out) + .default_value_fn(get_default_id_getter(tree.tree_interface, io_socket)); break; } case SOCK_CUSTOM: { - auto value = std::make_unique(); - value->init_socket_fn = get_init_socket_fn(ntree.tree_interface, io_socket); - value->idname_ = io_socket.socket_type; - dst = std::move(value); + decl = &b.add_socket(name, identifier, in_out) + .idname(io_socket.socket_type) + .init_socket_fn(get_init_socket_fn(tree.tree_interface, io_socket)); break; } } } else { - auto value = std::make_unique(); - value->init_socket_fn = get_init_socket_fn(ntree.tree_interface, io_socket); - value->idname_ = io_socket.socket_type; - dst = std::move(value); + decl = &b.add_socket(name, identifier, in_out) + .idname(io_socket.socket_type) + .init_socket_fn(get_init_socket_fn(tree.tree_interface, io_socket)); } - dst->name = io_socket.name ? io_socket.name : ""; - dst->identifier = io_socket.identifier; - dst->in_out = in_out; - dst->socket_type = datatype; - dst->description = io_socket.description ? io_socket.description : ""; - dst->hide_value = io_socket.flag & NODE_INTERFACE_SOCKET_HIDE_VALUE; - dst->compact = io_socket.flag & NODE_INTERFACE_SOCKET_COMPACT; - return dst; -} - -/* Socket items can be both input and output, generating 2 declarations for 1 item. Count the - * actual declarations generated by panel content to get the true size for UI drawing. */ -static int count_panel_declaration_children(const bNodeTreeInterfacePanel &io_panel) -{ - int num_child_decls = 0; - io_panel.foreach_item([&](const bNodeTreeInterfaceItem &item) { - switch (item.item_type) { - case NODE_INTERFACE_PANEL: - num_child_decls++; - break; - case NODE_INTERFACE_SOCKET: - const bNodeTreeInterfaceSocket &socket = - reinterpret_cast(item); - if (socket.flag & NODE_INTERFACE_SOCKET_INPUT) { - num_child_decls++; - } - if (socket.flag & NODE_INTERFACE_SOCKET_OUTPUT) { - num_child_decls++; - } - break; - } - return true; - }); - return num_child_decls; -} - -static PanelDeclarationPtr declaration_for_interface_panel(const bNodeTree & /*ntree*/, - const bNodeTreeInterfacePanel &io_panel) -{ - if (io_panel.items_num == 0) { - return nullptr; - } - - PanelDeclarationPtr dst = std::make_unique(); - dst->identifier = io_panel.identifier; - dst->name = io_panel.name ? io_panel.name : ""; - dst->description = io_panel.description ? io_panel.description : ""; - dst->default_collapsed = (io_panel.flag & NODE_INTERFACE_PANEL_DEFAULT_CLOSED); - dst->num_child_decls = count_panel_declaration_children(io_panel); - return dst; + decl->description(io_socket.description ? io_socket.description : ""); + decl->hide_value(io_socket.flag & NODE_INTERFACE_SOCKET_HIDE_VALUE); + decl->compact(io_socket.flag & NODE_INTERFACE_SOCKET_COMPACT); + return *decl; } static void set_default_input_field(const bNodeTreeInterfaceSocket &input, SocketDeclaration &decl) @@ -464,6 +400,31 @@ static void set_default_input_field(const bNodeTreeInterfaceSocket &input, Socke } } +static void node_group_declare_panel_recursive(DeclarationListBuilder &b, + const bNodeTree &group, + const bNodeTreeInterfacePanel &io_parent_panel) +{ + for (const bNodeTreeInterfaceItem *item : io_parent_panel.items()) { + switch (item->item_type) { + case NODE_INTERFACE_SOCKET: { + const auto &io_socket = node_interface::get_item_as(*item); + const eNodeSocketInOut in_out = (io_socket.flag & NODE_INTERFACE_SOCKET_INPUT) ? SOCK_IN : + SOCK_OUT; + build_interface_socket_declaration(group, io_socket, in_out, b); + break; + } + case NODE_INTERFACE_PANEL: { + const auto &io_panel = node_interface::get_item_as(*item); + auto &panel_b = b.add_panel(StringRef(io_panel.name), io_panel.identifier) + .description(StringRef(io_panel.description)) + .default_closed(io_panel.flag & NODE_INTERFACE_PANEL_DEFAULT_CLOSED); + node_group_declare_panel_recursive(panel_b, group, io_panel); + break; + } + } + } +} + void node_group_declare(NodeDeclarationBuilder &b) { const bNode *node = b.node_or_null(); @@ -484,41 +445,7 @@ void node_group_declare(NodeDeclarationBuilder &b) /* Allow the node group interface to define the socket order. */ r_declaration.use_custom_socket_order = true; - group->tree_interface.foreach_item([&](const bNodeTreeInterfaceItem &item) { - switch (item.item_type) { - case NODE_INTERFACE_SOCKET: { - const bNodeTreeInterfaceSocket &socket = - node_interface::get_item_as(item); - - SocketDeclarationPtr input_decl = (socket.flag & NODE_INTERFACE_SOCKET_INPUT) ? - declaration_for_interface_socket( - *group, socket, SOCK_IN) : - nullptr; - SocketDeclarationPtr output_decl = (socket.flag & NODE_INTERFACE_SOCKET_OUTPUT) ? - declaration_for_interface_socket( - *group, socket, SOCK_OUT) : - nullptr; - if (output_decl) { - r_declaration.outputs.append(output_decl.get()); - r_declaration.items.append(std::move(output_decl)); - } - if (input_decl) { - r_declaration.inputs.append(input_decl.get()); - r_declaration.items.append(std::move(input_decl)); - } - break; - } - case NODE_INTERFACE_PANEL: { - const bNodeTreeInterfacePanel &panel = - node_interface::get_item_as(item); - if (PanelDeclarationPtr panel_decl = declaration_for_interface_panel(*group, panel)) { - r_declaration.items.append(std::move(panel_decl)); - } - break; - } - } - return true; - }); + node_group_declare_panel_recursive(b, *group, group->tree_interface.root_panel); if (group->type == NTREE_GEOMETRY) { group->ensure_interface_cache(); @@ -746,26 +673,20 @@ static void group_input_declare(NodeDeclarationBuilder &b) if (node_tree == nullptr) { return; } - NodeDeclaration &r_declaration = b.declaration(); node_tree->tree_interface.foreach_item([&](const bNodeTreeInterfaceItem &item) { switch (item.item_type) { case NODE_INTERFACE_SOCKET: { const bNodeTreeInterfaceSocket &socket = node_interface::get_item_as(item); if (socket.flag & NODE_INTERFACE_SOCKET_INPUT) { - SocketDeclarationPtr socket_decl = declaration_for_interface_socket( - *node_tree, socket, SOCK_OUT); - r_declaration.outputs.append(socket_decl.get()); - r_declaration.items.append(std::move(socket_decl)); + build_interface_socket_declaration(*node_tree, socket, SOCK_OUT, b); } break; } } return true; }); - SocketDeclarationPtr extend_decl = decl::create_extend_declaration(SOCK_OUT); - r_declaration.outputs.append(extend_decl.get()); - r_declaration.items.append(std::move(extend_decl)); + b.add_output("", "__extend__"); } static void group_output_declare(NodeDeclarationBuilder &b) @@ -781,19 +702,14 @@ static void group_output_declare(NodeDeclarationBuilder &b) const bNodeTreeInterfaceSocket &socket = node_interface::get_item_as(item); if (socket.flag & NODE_INTERFACE_SOCKET_OUTPUT) { - SocketDeclarationPtr socket_decl = declaration_for_interface_socket( - *node_tree, socket, SOCK_IN); - r_declaration.inputs.append(socket_decl.get()); - r_declaration.items.append(std::move(socket_decl)); + build_interface_socket_declaration(*node_tree, socket, SOCK_IN, b); } break; } } return true; }); - SocketDeclarationPtr extend_decl = decl::create_extend_declaration(SOCK_IN); - r_declaration.inputs.append(extend_decl.get()); - r_declaration.items.append(std::move(extend_decl)); + b.add_input("", "__extend__"); } static bool group_input_insert_link(bNodeTree *ntree, bNode *node, bNodeLink *link) diff --git a/source/blender/nodes/intern/node_declaration.cc b/source/blender/nodes/intern/node_declaration.cc index 2837d95ccd2..bc30dc64af2 100644 --- a/source/blender/nodes/intern/node_declaration.cc +++ b/source/blender/nodes/intern/node_declaration.cc @@ -94,13 +94,18 @@ void NodeDeclarationBuilder::build_remaining_anonymous_attribute_relations() void NodeDeclarationBuilder::finalize() { this->build_remaining_anonymous_attribute_relations(); - BLI_assert(declaration_.is_valid()); +#ifndef NDEBUG + declaration_.assert_valid(); +#endif } NodeDeclarationBuilder::NodeDeclarationBuilder(NodeDeclaration &declaration, const bNodeTree *ntree, const bNode *node) - : declaration_(declaration), ntree_(ntree), node_(node) + : DeclarationListBuilder(*this, declaration.root_items), + declaration_(declaration), + ntree_(ntree), + node_(node) { } @@ -123,20 +128,6 @@ Span NodeDeclaration::sockets(eNodeSocketInOut in_out) cons return outputs; } -void NodeDeclarationBuilder::set_active_panel_builder(const PanelDeclarationBuilder *panel_builder) -{ - if (panel_builders_.is_empty()) { - BLI_assert(panel_builder == nullptr); - return; - } - - BLI_assert(!panel_builder || !panel_builder->is_complete_); - PanelDeclarationBuilder *last_panel_builder = panel_builders_.last().get(); - if (last_panel_builder != panel_builder) { - last_panel_builder->is_complete_ = true; - } -} - namespace anonymous_attribute_lifetime { std::ostream &operator<<(std::ostream &stream, const RelationsInNode &relations) @@ -168,95 +159,47 @@ std::ostream &operator<<(std::ostream &stream, const RelationsInNode &relations) } // namespace anonymous_attribute_lifetime -bool NodeDeclaration::is_valid() const +static void assert_valid_panels_recursive(const NodeDeclaration &node_decl, + const Span items, + Vector &r_flat_inputs, + Vector &r_flat_outputs) +{ + /* Expected item order unless any order is allowed: outputs, inputs, panels. */ + bool found_input = false; + bool found_panel = false; + + for (const ItemDeclaration *item_decl : items) { + if (const auto *socket_decl = dynamic_cast(item_decl)) { + if (socket_decl->in_out == SOCK_IN) { + BLI_assert(node_decl.allow_any_socket_order || !found_panel); + found_input = true; + r_flat_inputs.append(socket_decl); + } + else { + BLI_assert(node_decl.allow_any_socket_order || (!found_input && !found_panel)); + r_flat_outputs.append(socket_decl); + } + } + else if (const auto *panel_decl = dynamic_cast(item_decl)) { + found_panel = true; + assert_valid_panels_recursive(node_decl, panel_decl->items, r_flat_inputs, r_flat_outputs); + } + } +} + +void NodeDeclaration::assert_valid() const { if (!this->use_custom_socket_order) { - /* Skip validation for conventional socket layouts. */ - return true; + /* Skip validation for conventional socket layouts. Those are reordered in drawing code. */ + return; } - /* Validation state for the interface root items as well as any panel content. */ - struct ValidationState { - /* Remaining number of items expected in a panel */ - int remaining_items = 0; - /* Sockets first, followed by panels. */ - NodeTreeInterfaceItemType item_type = NODE_INTERFACE_SOCKET; - /* Output sockets first, followed by input sockets. */ - eNodeSocketInOut socket_in_out = SOCK_OUT; - }; + Vector flat_inputs; + Vector flat_outputs; + assert_valid_panels_recursive(*this, this->root_items, flat_inputs, flat_outputs); - Stack panel_states; - panel_states.push({}); - - for (const ItemDeclarationPtr &item_decl : items) { - BLI_assert(panel_states.size() >= 1); - ValidationState &state = panel_states.peek(); - - if (const SocketDeclaration *socket_decl = dynamic_cast( - item_decl.get())) - { - if (state.item_type != NODE_INTERFACE_SOCKET && !this->allow_any_socket_order) { - std::cout << "Socket added after panel" << std::endl; - return false; - } - - /* Check for consistent outputs.., inputs.. blocks. */ - if (state.socket_in_out == SOCK_OUT && socket_decl->in_out == SOCK_IN) { - /* Start of input sockets. */ - state.socket_in_out = SOCK_IN; - } - if (socket_decl->in_out != state.socket_in_out && !this->allow_any_socket_order) { - std::cout << "Output socket added after input socket" << std::endl; - return false; - } - - /* Item counting for the panels, but ignore for root items. */ - if (panel_states.size() > 1) { - if (state.remaining_items <= 0) { - std::cout << "More sockets than expected in panel" << std::endl; - return false; - } - --state.remaining_items; - /* Panel closed after last item is added. */ - if (state.remaining_items == 0) { - panel_states.pop(); - } - } - } - else if (const PanelDeclaration *panel_decl = dynamic_cast( - item_decl.get())) - { - if (state.item_type == NODE_INTERFACE_SOCKET) { - /* Start of panels section */ - state.item_type = NODE_INTERFACE_PANEL; - } - BLI_assert(state.item_type == NODE_INTERFACE_PANEL); - - if (panel_decl->num_child_decls > 0) { - /* New panel started. */ - panel_states.push({panel_decl->num_child_decls}); - } - } - else if (dynamic_cast(item_decl.get())) { - if (panel_states.size() > 1) { - --state.remaining_items; - if (state.remaining_items == 0) { - panel_states.pop(); - } - } - } - else { - BLI_assert_unreachable(); - return false; - } - } - - /* All panels complete? */ - if (panel_states.size() != 1) { - std::cout << "Incomplete last panel" << std::endl; - return false; - } - return true; + BLI_assert(this->inputs.as_span() == flat_inputs); + BLI_assert(this->outputs.as_span() == flat_outputs); } bool NodeDeclaration::matches(const bNode &node) const @@ -264,7 +207,7 @@ bool NodeDeclaration::matches(const bNode &node) const const bNodeSocket *current_input = static_cast(node.inputs.first); const bNodeSocket *current_output = static_cast(node.outputs.first); const bNodePanelState *current_panel = node.panel_states_array; - for (const ItemDeclarationPtr &item_decl : items) { + for (const ItemDeclarationPtr &item_decl : this->all_items) { if (const SocketDeclaration *socket_decl = dynamic_cast( item_decl.get())) { @@ -358,51 +301,6 @@ bool SocketDeclaration::matches_common_data(const bNodeSocket &socket) const return true; } -PanelDeclarationBuilder &NodeDeclarationBuilder::add_panel(StringRef name, int identifier) -{ - std::unique_ptr panel_decl = std::make_unique(); - std::unique_ptr panel_decl_builder = - std::make_unique(); - panel_decl_builder->decl_ = &*panel_decl; - - panel_decl_builder->node_decl_builder_ = this; - if (identifier >= 0) { - panel_decl->identifier = identifier; - } - else { - /* Use index as identifier. */ - panel_decl->identifier = declaration_.items.size(); - } - panel_decl->name = name; - declaration_.items.append(std::move(panel_decl)); - - PanelDeclarationBuilder &builder_ref = *panel_decl_builder; - panel_builders_.append(std::move(panel_decl_builder)); - set_active_panel_builder(&builder_ref); - - return builder_ref; -} - -void PanelDeclaration::build(bNodePanelState &panel) const -{ - panel = {0}; - panel.identifier = this->identifier; - SET_FLAG_FROM_TEST(panel.flag, this->default_collapsed, NODE_PANEL_COLLAPSED); -} - -bool PanelDeclaration::matches(const bNodePanelState &panel) const -{ - return panel.identifier == this->identifier; -} - -void PanelDeclaration::update_or_build(const bNodePanelState &old_panel, - bNodePanelState &new_panel) const -{ - build(new_panel); - /* Copy existing state to the new panel */ - SET_FLAG_FROM_TEST(new_panel.flag, old_panel.is_collapsed(), NODE_PANEL_COLLAPSED); -} - template static bool socket_type_to_static_decl_type(const eNodeSocketDatatype socket_type, Fn &&fn) { @@ -465,7 +363,7 @@ std::unique_ptr make_declaration_for_socket_type( return decl; } -BaseSocketDeclarationBuilder &NodeDeclarationBuilder::add_input( +BaseSocketDeclarationBuilder &DeclarationListBuilder::add_input( const eNodeSocketDatatype socket_type, const StringRef name, const StringRef identifier) { BaseSocketDeclarationBuilder *decl = nullptr; @@ -480,14 +378,14 @@ BaseSocketDeclarationBuilder &NodeDeclarationBuilder::add_input( return *decl; } -BaseSocketDeclarationBuilder &NodeDeclarationBuilder::add_input(const eCustomDataType data_type, +BaseSocketDeclarationBuilder &DeclarationListBuilder::add_input(const eCustomDataType data_type, const StringRef name, const StringRef identifier) { return this->add_input(*bke::custom_data_type_to_socket_type(data_type), name, identifier); } -BaseSocketDeclarationBuilder &NodeDeclarationBuilder::add_output( +BaseSocketDeclarationBuilder &DeclarationListBuilder::add_output( const eNodeSocketDatatype socket_type, const StringRef name, const StringRef identifier) { BaseSocketDeclarationBuilder *decl = nullptr; @@ -502,69 +400,61 @@ BaseSocketDeclarationBuilder &NodeDeclarationBuilder::add_output( return *decl; } -BaseSocketDeclarationBuilder &NodeDeclarationBuilder::add_output(const eCustomDataType data_type, +BaseSocketDeclarationBuilder &DeclarationListBuilder::add_output(const eCustomDataType data_type, const StringRef name, const StringRef identifier) { return this->add_output(*bke::custom_data_type_to_socket_type(data_type), name, identifier); } -void NodeDeclarationBuilder::add_separator() +void DeclarationListBuilder::add_separator() { - declaration_.items.append(std::make_unique()); + auto decl_ptr = std::make_unique(); + SeparatorDeclaration &decl = *decl_ptr; + this->node_decl_builder.declaration_.all_items.append(std::move(decl_ptr)); + this->items.append(&decl); } -BaseSocketDeclarationBuilder &PanelDeclarationBuilder::add_input( - const eNodeSocketDatatype socket_type, const StringRef name, const StringRef identifier) +PanelDeclarationBuilder &DeclarationListBuilder::add_panel(const StringRef name, int identifier) { - BaseSocketDeclarationBuilder *decl = nullptr; - socket_type_to_static_decl_type(socket_type, [&](auto type_tag) { - using DeclT = typename decltype(type_tag)::type; - decl = &this->add_input(name, identifier); - }); - if (!decl) { - BLI_assert_unreachable(); - decl = &this->add_input("", ""); + auto panel_decl_ptr = std::make_unique(); + PanelDeclaration &panel_decl = *panel_decl_ptr; + auto panel_decl_builder_ptr = std::make_unique(this->node_decl_builder, + panel_decl); + PanelDeclarationBuilder &panel_decl_builder = *panel_decl_builder_ptr; + + if (identifier >= 0) { + panel_decl.identifier = identifier; } - return *decl; -} - -BaseSocketDeclarationBuilder &PanelDeclarationBuilder::add_input(const eCustomDataType data_type, - const StringRef name, - const StringRef identifier) -{ - return this->add_input(*bke::custom_data_type_to_socket_type(data_type), name, identifier); -} - -BaseSocketDeclarationBuilder &PanelDeclarationBuilder::add_output( - const eNodeSocketDatatype socket_type, const StringRef name, const StringRef identifier) -{ - BaseSocketDeclarationBuilder *decl = nullptr; - socket_type_to_static_decl_type(socket_type, [&](auto type_tag) { - using DeclT = typename decltype(type_tag)::type; - decl = &this->add_output(name, identifier); - }); - if (!decl) { - BLI_assert_unreachable(); - decl = &this->add_output("", ""); + else { + /* Use index as identifier. */ + panel_decl.identifier = this->node_decl_builder.declaration_.all_items.size(); } - return *decl; + panel_decl.name = name; + this->node_decl_builder.declaration_.all_items.append(std::move(panel_decl_ptr)); + this->node_decl_builder.panel_builders_.append(std::move(panel_decl_builder_ptr)); + this->items.append(&panel_decl); + return panel_decl_builder; } -BaseSocketDeclarationBuilder &PanelDeclarationBuilder::add_output(const eCustomDataType data_type, - const StringRef name, - const StringRef identifier) +void PanelDeclaration::build(bNodePanelState &panel) const { - return this->add_output(*bke::custom_data_type_to_socket_type(data_type), name, identifier); + panel = {0}; + panel.identifier = this->identifier; + SET_FLAG_FROM_TEST(panel.flag, this->default_collapsed, NODE_PANEL_COLLAPSED); } -void PanelDeclarationBuilder::add_separator() +bool PanelDeclaration::matches(const bNodePanelState &panel) const { - if (is_complete_) { - BLI_assert_unreachable(); - } - ++this->decl_->num_child_decls; - node_decl_builder_->add_separator(); + return panel.identifier == this->identifier; +} + +void PanelDeclaration::update_or_build(const bNodePanelState &old_panel, + bNodePanelState &new_panel) const +{ + build(new_panel); + /* Copy existing state to the new panel */ + SET_FLAG_FROM_TEST(new_panel.flag, old_panel.is_collapsed(), NODE_PANEL_COLLAPSED); } BaseSocketDeclarationBuilder &BaseSocketDeclarationBuilder::supports_field() @@ -603,6 +493,12 @@ BaseSocketDeclarationBuilder &BaseSocketDeclarationBuilder::multi_input(bool val return *this; } +BaseSocketDeclarationBuilder &BaseSocketDeclarationBuilder::compact(bool value) +{ + decl_base_->compact = value; + return *this; +} + BaseSocketDeclarationBuilder &BaseSocketDeclarationBuilder::reference_pass( const Span input_indices) { diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc index ff550e83bc4..ce0e667eb8a 100644 --- a/source/blender/nodes/intern/node_socket.cc +++ b/source/blender/nodes/intern/node_socket.cc @@ -422,7 +422,7 @@ static void refresh_node_sockets_and_panels(bNodeTree &ntree, /* Count panels */ int new_num_panels = 0; - for (const ItemDeclarationPtr &item_decl : node_decl.items) { + for (const ItemDeclarationPtr &item_decl : node_decl.all_items) { if (dynamic_cast(item_decl.get())) { ++new_num_panels; } @@ -451,7 +451,7 @@ static void refresh_node_sockets_and_panels(bNodeTree &ntree, VectorSet new_inputs; VectorSet new_outputs; bNodePanelState *new_panel = node.panel_states_array; - for (const ItemDeclarationPtr &item_decl : node_decl.items) { + for (const ItemDeclarationPtr &item_decl : node_decl.all_items) { if (const SocketDeclaration *socket_decl = dynamic_cast( item_decl.get())) { diff --git a/source/blender/nodes/intern/node_socket_declarations.cc b/source/blender/nodes/intern/node_socket_declarations.cc index 542ace7218b..d85cadd4a62 100644 --- a/source/blender/nodes/intern/node_socket_declarations.cc +++ b/source/blender/nodes/intern/node_socket_declarations.cc @@ -830,15 +830,6 @@ bNodeSocket &Custom::update_or_build(bNodeTree &ntree, bNode &node, bNodeSocket return socket; } -SocketDeclarationPtr create_extend_declaration(const eNodeSocketInOut in_out) -{ - std::unique_ptr decl = std::make_unique(); - decl->name = ""; - decl->identifier = "__extend__"; - decl->in_out = in_out; - return decl; -} - /** \} */ } // namespace blender::nodes::decl