Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2021-10-15 13:12:36 +0300
committerJacques Lucke <jacques@blender.org>2021-10-15 13:12:56 +0300
commitaca38148ad56c27840de1ee6ebb7bd1841ab0ca4 (patch)
treeee5cd4875122b06423f67559303af65e8ed1f0d4 /source/blender/editors/space_node/node_templates.cc
parente46055ae9dbd77271878b35cdd061cb7cc7e1afc (diff)
Fix T92131: handle node declaration in material properties
The issue was that this menu was only looking at socket templates, but not at the new node declarations. This fix is to just check those as well. The fix comes with a small refactor that makes the memory management a bit simpler. Differential Revision: https://developer.blender.org/D12866
Diffstat (limited to 'source/blender/editors/space_node/node_templates.cc')
-rw-r--r--source/blender/editors/space_node/node_templates.cc168
1 files changed, 92 insertions, 76 deletions
diff --git a/source/blender/editors/space_node/node_templates.cc b/source/blender/editors/space_node/node_templates.cc
index 648ede7abd5..f68d8589624 100644
--- a/source/blender/editors/space_node/node_templates.cc
+++ b/source/blender/editors/space_node/node_templates.cc
@@ -20,6 +20,7 @@
#include <cstdlib>
#include <cstring>
+#include <optional>
#include "MEM_guardedalloc.h"
@@ -39,7 +40,9 @@
#include "RNA_access.h"
+#include "NOD_node_declaration.hh"
#include "NOD_socket.h"
+#include "NOD_socket_declarations.hh"
#include "../interface/interface_intern.h" /* XXX bad level */
#include "UI_interface.h"
@@ -49,17 +52,20 @@
#include "ED_undo.h"
+using blender::Vector;
+using blender::nodes::NodeDeclaration;
+
/************************* Node Socket Manipulation **************************/
/* describes an instance of a node type and a specific socket to link */
struct NodeLinkItem {
- int socket_index; /* index for linking */
- int socket_type; /* socket type for compatibility check */
- const char *socket_name; /* ui label of the socket */
- const char *node_name; /* ui label of the node */
+ int socket_index = -1; /* index for linking */
+ int socket_type = SOCK_CUSTOM; /* socket type for compatibility check */
+ const char *socket_name = nullptr; /* ui label of the socket */
+ const char *node_name = nullptr; /* ui label of the node */
/* extra settings */
- bNodeTree *ngroup; /* group node tree */
+ bNodeTree *ngroup = nullptr; /* group node tree */
};
/* Compare an existing node to a link item to see if it can be reused.
@@ -319,15 +325,13 @@ struct NodeLinkArg {
uiLayout *layout;
};
-static void ui_node_link_items(NodeLinkArg *arg,
- int in_out,
- NodeLinkItem **r_items,
- int *r_totitems)
+static Vector<NodeLinkItem> ui_node_link_items(NodeLinkArg *arg,
+ int in_out,
+ std::optional<NodeDeclaration> &r_node_decl)
{
- /* XXX this should become a callback for node types! */
- NodeLinkItem *items = nullptr;
- int totitems = 0;
+ Vector<NodeLinkItem> items;
+ /* XXX this should become a callback for node types! */
if (arg->node_type->type == NODE_GROUP) {
bNodeTree *ngroup;
int i;
@@ -339,69 +343,86 @@ static void ui_node_link_items(NodeLinkArg *arg,
!nodeGroupPoll(arg->ntree, ngroup, &disabled_hint)) {
continue;
}
-
- ListBase *lb = ((in_out == SOCK_IN) ? &ngroup->inputs : &ngroup->outputs);
- totitems += BLI_listbase_count(lb);
}
- if (totitems > 0) {
- items = (NodeLinkItem *)MEM_callocN(sizeof(NodeLinkItem) * totitems, "ui node link items");
-
- i = 0;
- for (ngroup = (bNodeTree *)arg->bmain->nodetrees.first; ngroup;
- ngroup = (bNodeTree *)ngroup->id.next) {
- const char *disabled_hint;
- if ((ngroup->type != arg->ntree->type) ||
- !nodeGroupPoll(arg->ntree, ngroup, &disabled_hint)) {
- continue;
- }
+ i = 0;
+ for (ngroup = (bNodeTree *)arg->bmain->nodetrees.first; ngroup;
+ ngroup = (bNodeTree *)ngroup->id.next) {
+ const char *disabled_hint;
+ if ((ngroup->type != arg->ntree->type) ||
+ !nodeGroupPoll(arg->ntree, ngroup, &disabled_hint)) {
+ continue;
+ }
- ListBase *lb = (in_out == SOCK_IN ? &ngroup->inputs : &ngroup->outputs);
- bNodeSocket *stemp;
- int index;
- for (stemp = (bNodeSocket *)lb->first, index = 0; stemp;
- stemp = stemp->next, index++, i++) {
- NodeLinkItem *item = &items[i];
-
- item->socket_index = index;
- /* NOTE: int stemp->type is not fully reliable, not used for node group
- * interface sockets. use the typeinfo->type instead.
- */
- item->socket_type = stemp->typeinfo->type;
- item->socket_name = stemp->name;
- item->node_name = ngroup->id.name + 2;
- item->ngroup = ngroup;
- }
+ ListBase *lb = (in_out == SOCK_IN ? &ngroup->inputs : &ngroup->outputs);
+ bNodeSocket *stemp;
+ int index;
+ for (stemp = (bNodeSocket *)lb->first, index = 0; stemp; stemp = stemp->next, index++, i++) {
+ NodeLinkItem item;
+ item.socket_index = index;
+ /* NOTE: int stemp->type is not fully reliable, not used for node group
+ * interface sockets. use the typeinfo->type instead.
+ */
+ item.socket_type = stemp->typeinfo->type;
+ item.socket_name = stemp->name;
+ item.node_name = ngroup->id.name + 2;
+ item.ngroup = ngroup;
+
+ items.append(item);
}
}
}
+ else if (arg->node_type->declare != nullptr) {
+ using namespace blender;
+ using namespace blender::nodes;
+
+ r_node_decl.emplace(NodeDeclaration());
+ NodeDeclarationBuilder node_decl_builder{*r_node_decl};
+ arg->node_type->declare(node_decl_builder);
+ Span<SocketDeclarationPtr> socket_decls = (in_out == SOCK_IN) ? r_node_decl->inputs() :
+ r_node_decl->outputs();
+ int index = 0;
+ for (const SocketDeclarationPtr &socket_decl_ptr : socket_decls) {
+ const SocketDeclaration &socket_decl = *socket_decl_ptr;
+ NodeLinkItem item;
+ item.socket_index = index++;
+ /* A socket declaration does not necessarily map to exactly one built-in socket type. So only
+ * check for the types that matter here. */
+ if (dynamic_cast<const decl::Color *>(&socket_decl)) {
+ item.socket_type = SOCK_RGBA;
+ }
+ else if (dynamic_cast<const decl::Float *>(&socket_decl)) {
+ item.socket_type = SOCK_FLOAT;
+ }
+ else if (dynamic_cast<const decl::Vector *>(&socket_decl)) {
+ item.socket_type = SOCK_VECTOR;
+ }
+ else {
+ item.socket_type = SOCK_CUSTOM;
+ }
+ item.socket_name = socket_decl.name().c_str();
+ item.node_name = arg->node_type->ui_name;
+ items.append(item);
+ }
+ }
else {
bNodeSocketTemplate *socket_templates = (in_out == SOCK_IN ? arg->node_type->inputs :
arg->node_type->outputs);
bNodeSocketTemplate *stemp;
int i;
- for (stemp = socket_templates; stemp && stemp->type != -1; stemp++) {
- totitems++;
- }
-
- if (totitems > 0) {
- items = (NodeLinkItem *)MEM_callocN(sizeof(NodeLinkItem) * totitems, "ui node link items");
-
- i = 0;
- for (stemp = socket_templates; stemp && stemp->type != -1; stemp++, i++) {
- NodeLinkItem *item = &items[i];
-
- item->socket_index = i;
- item->socket_type = stemp->type;
- item->socket_name = stemp->name;
- item->node_name = arg->node_type->ui_name;
- }
+ i = 0;
+ for (stemp = socket_templates; stemp && stemp->type != -1; stemp++, i++) {
+ NodeLinkItem item;
+ item.socket_index = i;
+ item.socket_type = stemp->type;
+ item.socket_name = stemp->name;
+ item.node_name = arg->node_type->ui_name;
+ items.append(item);
}
}
- *r_items = items;
- *r_totitems = totitems;
+ return items;
}
static void ui_node_link(bContext *C, void *arg_p, void *event_p)
@@ -513,8 +534,6 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
/* generate UI */
for (int j = 0; j < sorted_ntypes.size(); j++) {
bNodeType *ntype = sorted_ntypes[j];
- NodeLinkItem *items;
- int totitems;
char name[UI_MAX_NAME_STR];
const char *cur_node_name = nullptr;
int num = 0;
@@ -522,16 +541,17 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
arg->node_type = ntype;
- ui_node_link_items(arg, SOCK_OUT, &items, &totitems);
+ std::optional<blender::nodes::NodeDeclaration> node_decl;
+ Vector<NodeLinkItem> items = ui_node_link_items(arg, SOCK_OUT, node_decl);
- for (int i = 0; i < totitems; i++) {
- if (ui_compatible_sockets(items[i].socket_type, sock->type)) {
+ for (const NodeLinkItem &item : items) {
+ if (ui_compatible_sockets(item.socket_type, sock->type)) {
num++;
}
}
- for (int i = 0; i < totitems; i++) {
- if (!ui_compatible_sockets(items[i].socket_type, sock->type)) {
+ for (const NodeLinkItem &item : items) {
+ if (!ui_compatible_sockets(item.socket_type, sock->type)) {
continue;
}
@@ -546,8 +566,8 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
}
if (num > 1) {
- if (!cur_node_name || !STREQ(cur_node_name, items[i].node_name)) {
- cur_node_name = items[i].node_name;
+ if (!cur_node_name || !STREQ(cur_node_name, item.node_name)) {
+ cur_node_name = item.node_name;
/* XXX Do not use uiItemL here,
* it would add an empty icon as we are in a menu! */
uiDefBut(block,
@@ -566,11 +586,11 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
"");
}
- BLI_snprintf(name, UI_MAX_NAME_STR, "%s", IFACE_(items[i].socket_name));
+ BLI_snprintf(name, UI_MAX_NAME_STR, "%s", IFACE_(item.socket_name));
icon = ICON_BLANK1;
}
else {
- BLI_strncpy(name, IFACE_(items[i].node_name), UI_MAX_NAME_STR);
+ BLI_strncpy(name, IFACE_(item.node_name), UI_MAX_NAME_STR);
icon = ICON_NONE;
}
@@ -591,13 +611,9 @@ static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
TIP_("Add node to input"));
argN = (NodeLinkArg *)MEM_dupallocN(arg);
- argN->item = items[i];
+ argN->item = item;
UI_but_funcN_set(but, ui_node_link, argN, nullptr);
}
-
- if (items) {
- MEM_freeN(items);
- }
}
}