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:
authorLukas Tönne <lukas.toenne@gmail.com>2021-07-06 20:36:11 +0300
committerLukas Tönne <lukas.toenne@gmail.com>2021-07-06 20:36:11 +0300
commit586cf8b1905257bf0f7d9c20b5333271f9cab3e9 (patch)
tree5fa77626641c47f4274b9145a1f1702512fc92b6
parent933eddc9a113b40849895922f2dc350305809ebd (diff)
Nodes: Adds button to groups to change type of sockets.
The menu lists all socket types that are valid for the node tree. Changing a socket type updates all instances of the group and keeps existing links to the socket. If changing the socket type leads to incorrect node connections the links are flagged as invalid (red) and ignored but not removed. This is so users don't lose information and can then fix resulting issues. For example: Changing a Color socket to a Shader socket can cause an invalid Shader-to-Color connection. Implementation details: The new `NODE_OT_tree_socket_change_type` operator uses the generic `rna_node_socket_type_itemf` function to list all eligible socket types. It uses the tree type's `valid_socket_type` callback to test for valid types. In addition it also checks the subtype, because multiple RNA types are registered for the same base type. The `valid_socket_type` callback has been modified slightly to accept full socket types instead of just the base type enum, so that custom (python) socket types can be used by this operator. The `nodeModifySocketType` function is now called when group nodes encounter a socket type mismatch, instead of replacing the socket entirely. This ensures that links are kept to/from group nodes as well as group input/output nodes. The `nodeModifySocketType` function now also takes a full `bNodeSocketType` instead of just the base and subtype enum (a shortcut `nodeModifySocketTypeStatic` exists for when only static types are used). Differential Revision: https://developer.blender.org/D10912
-rw-r--r--source/blender/blenkernel/BKE_node.h17
-rw-r--r--source/blender/blenkernel/intern/node.cc76
-rw-r--r--source/blender/editors/space_node/node_buttons.c31
-rw-r--r--source/blender/editors/space_node/node_edit.cc103
-rw-r--r--source/blender/editors/space_node/node_intern.h1
-rw-r--r--source/blender/editors/space_node/node_ops.c1
-rw-r--r--source/blender/makesrna/RNA_access.h1
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c26
-rw-r--r--source/blender/nodes/composite/node_composite_tree.c7
-rw-r--r--source/blender/nodes/geometry/node_geometry_tree.cc28
-rw-r--r--source/blender/nodes/intern/node_common.c9
-rw-r--r--source/blender/nodes/intern/node_socket.cc4
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c7
-rw-r--r--source/blender/nodes/texture/node_texture_tree.c7
14 files changed, 273 insertions, 45 deletions
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 7f4189a3a4a..301fe875d79 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -141,7 +141,10 @@ typedef void *SocketGetCPPValueFunction;
* Defines the appearance and behavior of a socket in the UI.
*/
typedef struct bNodeSocketType {
- char idname[64]; /* identifier name */
+ /* Identifier name */
+ char idname[64];
+ /* Type label */
+ char label[64];
void (*draw)(struct bContext *C,
struct uiLayout *layout,
@@ -412,7 +415,7 @@ typedef struct bNodeTreeType {
void (*node_add_init)(struct bNodeTree *ntree, struct bNode *bnode);
/* Check if the socket type is valid for this tree type. */
- bool (*valid_socket_type)(enum eNodeSocketDatatype socket_type, struct bNodeTreeType *ntreetype);
+ bool (*valid_socket_type)(struct bNodeTreeType *ntreetype, struct bNodeSocketType *socket_type);
/* RNA integration */
ExtensionRNA rna_ext;
@@ -554,8 +557,12 @@ void nodeRegisterSocketType(struct bNodeSocketType *stype);
void nodeUnregisterSocketType(struct bNodeSocketType *stype);
bool nodeSocketIsRegistered(struct bNodeSocket *sock);
struct GHashIterator *nodeSocketTypeGetIterator(void);
+const char *nodeSocketTypeLabel(const bNodeSocketType *stype);
+
+bool nodeIsStaticSocketType(const struct bNodeSocketType *stype);
const char *nodeStaticSocketType(int type, int subtype);
const char *nodeStaticSocketInterfaceType(int type, int subtype);
+const char *nodeStaticSocketLabel(int type, int subtype);
/* helper macros for iterating over node types */
#define NODE_SOCKET_TYPES_BEGIN(stype) \
@@ -605,7 +612,11 @@ struct bNodeSocket *nodeInsertStaticSocket(struct bNodeTree *ntree,
const char *name);
void nodeRemoveSocket(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock);
void nodeRemoveAllSockets(struct bNodeTree *ntree, struct bNode *node);
-void nodeModifySocketType(
+void nodeModifySocketType(struct bNodeTree *ntree,
+ struct bNode *node,
+ struct bNodeSocket *sock,
+ const char *idname);
+void nodeModifySocketTypeStatic(
struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock, int type, int subtype);
struct bNode *nodeAddNode(const struct bContext *C, struct bNodeTree *ntree, const char *idname);
diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc
index f6105bac1a8..6a6cc3ffaad 100644
--- a/source/blender/blenkernel/intern/node.cc
+++ b/source/blender/blenkernel/intern/node.cc
@@ -1425,6 +1425,12 @@ GHashIterator *nodeSocketTypeGetIterator(void)
return BLI_ghashIterator_new(nodesockettypes_hash);
}
+const char *nodeSocketTypeLabel(const bNodeSocketType *stype)
+{
+ /* Use socket type name as a fallback if label is undefined. */
+ return stype->label[0] != '\0' ? stype->label : RNA_struct_ui_name(stype->ext_socket.srna);
+}
+
struct bNodeSocket *nodeFindSocket(const bNode *node,
eNodeSocketInOut in_out,
const char *identifier)
@@ -1585,13 +1591,15 @@ static void socket_id_user_decrement(bNodeSocket *sock)
}
}
-void nodeModifySocketType(
- bNodeTree *ntree, bNode *UNUSED(node), bNodeSocket *sock, int type, int subtype)
+void nodeModifySocketType(bNodeTree *ntree,
+ bNode *UNUSED(node),
+ bNodeSocket *sock,
+ const char *idname)
{
- const char *idname = nodeStaticSocketType(type, subtype);
+ bNodeSocketType *socktype = nodeSocketTypeFind(idname);
- if (!idname) {
- CLOG_ERROR(&LOG, "static node socket type %d undefined", type);
+ if (!socktype) {
+ CLOG_ERROR(&LOG, "node socket type %s undefined", idname);
return;
}
@@ -1601,9 +1609,21 @@ void nodeModifySocketType(
sock->default_value = nullptr;
}
- sock->type = type;
BLI_strncpy(sock->idname, idname, sizeof(sock->idname));
- node_socket_set_typeinfo(ntree, sock, nodeSocketTypeFind(idname));
+ node_socket_set_typeinfo(ntree, sock, socktype);
+}
+
+void nodeModifySocketTypeStatic(
+ bNodeTree *ntree, bNode *node, bNodeSocket *sock, int type, int subtype)
+{
+ const char *idname = nodeStaticSocketType(type, subtype);
+
+ if (!idname) {
+ CLOG_ERROR(&LOG, "static node socket type %d undefined", type);
+ return;
+ }
+
+ nodeModifySocketType(ntree, node, sock, idname);
}
bNodeSocket *nodeAddSocket(bNodeTree *ntree,
@@ -1647,6 +1667,15 @@ bNodeSocket *nodeInsertSocket(bNodeTree *ntree,
return sock;
}
+bool nodeIsStaticSocketType(const struct bNodeSocketType *stype)
+{
+ /*
+ * Cannot rely on type==SOCK_CUSTOM here, because type is 0 by default
+ * and can be changed on custom sockets.
+ */
+ return RNA_struct_is_a(stype->ext_socket.srna, &RNA_NodeSocketStandard);
+}
+
const char *nodeStaticSocketType(int type, int subtype)
{
switch (type) {
@@ -1801,6 +1830,39 @@ const char *nodeStaticSocketInterfaceType(int type, int subtype)
return nullptr;
}
+const char *nodeStaticSocketLabel(int type, int UNUSED(subtype))
+{
+ switch (type) {
+ case SOCK_FLOAT:
+ return "Float";
+ case SOCK_INT:
+ return "Integer";
+ case SOCK_BOOLEAN:
+ return "Boolean";
+ case SOCK_VECTOR:
+ return "Vector";
+ case SOCK_RGBA:
+ return "Color";
+ case SOCK_STRING:
+ return "String";
+ case SOCK_SHADER:
+ return "Shader";
+ case SOCK_OBJECT:
+ return "Object";
+ case SOCK_IMAGE:
+ return "Image";
+ case SOCK_GEOMETRY:
+ return "Geometry";
+ case SOCK_COLLECTION:
+ return "Collection";
+ case SOCK_TEXTURE:
+ return "Texture";
+ case SOCK_MATERIAL:
+ return "Material";
+ }
+ return nullptr;
+}
+
bNodeSocket *nodeAddStaticSocket(bNodeTree *ntree,
bNode *node,
eNodeSocketInOut in_out,
diff --git a/source/blender/editors/space_node/node_buttons.c b/source/blender/editors/space_node/node_buttons.c
index 336b0c46a81..a55cc21fb16 100644
--- a/source/blender/editors/space_node/node_buttons.c
+++ b/source/blender/editors/space_node/node_buttons.c
@@ -151,10 +151,37 @@ static void draw_socket_list(const bContext *C,
bNodeSocket *socket = node_tree_find_active_socket(ntree, in_out);
if (socket != NULL) {
- uiLayoutSetPropSep(layout, true);
- uiLayoutSetPropDecorate(layout, false);
PointerRNA socket_ptr;
RNA_pointer_create((ID *)ntree, &RNA_NodeSocketInterface, socket, &socket_ptr);
+
+ {
+ /* Mimicking property split */
+ uiLayoutSetPropSep(layout, false);
+ uiLayoutSetPropDecorate(layout, false);
+ uiLayout *layout_row = uiLayoutRow(layout, true);
+ uiLayout *layout_split = uiLayoutSplit(layout_row, 0.4f, true);
+
+ uiLayout *label_column = uiLayoutColumn(layout_split, true);
+ uiLayoutSetAlignment(label_column, UI_LAYOUT_ALIGN_RIGHT);
+ /* Menu to change the socket type. */
+ uiItemL(label_column, "Type", ICON_NONE);
+
+ uiLayout *property_row = uiLayoutRow(layout_split, true);
+
+ PointerRNA props_ptr;
+ uiItemMenuEnumFullO(property_row,
+ (bContext *)C,
+ "NODE_OT_tree_socket_change_type",
+ "socket_type",
+ nodeSocketTypeLabel(socket->typeinfo),
+ ICON_NONE,
+ &props_ptr);
+ RNA_enum_set(&props_ptr, "in_out", in_out);
+ }
+
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+
uiItemR(layout, &socket_ptr, "name", 0, NULL, ICON_NONE);
/* Display descriptions only for Geometry Nodes, since it's only used in the modifier panel. */
diff --git a/source/blender/editors/space_node/node_edit.cc b/source/blender/editors/space_node/node_edit.cc
index 9a6603eb589..e6f23b89a02 100644
--- a/source/blender/editors/space_node/node_edit.cc
+++ b/source/blender/editors/space_node/node_edit.cc
@@ -2414,6 +2414,109 @@ void NODE_OT_tree_socket_remove(wmOperatorType *ot)
RNA_def_enum(ot->srna, "in_out", rna_enum_node_socket_in_out_items, SOCK_IN, "Socket Type", "");
}
+/********************** Change interface socket type operator *********************/
+
+static int ntree_socket_change_type_exec(bContext *C, wmOperator *op)
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNodeTree *ntree = snode->edittree;
+ const eNodeSocketInOut in_out = (eNodeSocketInOut)RNA_enum_get(op->ptr, "in_out");
+ const bNodeSocketType *socket_type = rna_node_socket_type_from_enum(
+ RNA_enum_get(op->ptr, "socket_type"));
+ ListBase *sockets = (in_out == SOCK_IN) ? &ntree->inputs : &ntree->outputs;
+
+ Main *main = CTX_data_main(C);
+
+ bNodeSocket *iosock = ntree_get_active_interface_socket(sockets);
+ if (iosock == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* The type remains the same, so we don't need to change anything. */
+ if (iosock->typeinfo == socket_type) {
+ return OPERATOR_FINISHED;
+ }
+
+ /* Don't handle subtypes for now. */
+ nodeModifySocketType(ntree, NULL, iosock, socket_type->idname);
+
+ /* Need the extra update here because the loop above does not check for valid links in the node
+ * group we're currently editing. */
+ ntree->update |= NTREE_UPDATE_GROUP | NTREE_UPDATE_LINKS;
+
+ /* Deactivate sockets. */
+ LISTBASE_FOREACH (bNodeSocket *, socket_iter, sockets) {
+ socket_iter->flag &= ~SELECT;
+ }
+ /* Make the new socket active. */
+ iosock->flag |= SELECT;
+
+ ntreeUpdateTree(main, ntree);
+
+ snode_notify(C, snode);
+ snode_dag_update(C, snode);
+
+ WM_event_add_notifier(C, NC_NODE | ND_DISPLAY, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static bool socket_change_poll_type(void *userdata, bNodeSocketType *socket_type)
+{
+ /* Check if the node tree supports the socket type. */
+ bNodeTreeType *ntreetype = (bNodeTreeType *)userdata;
+ if (ntreetype->valid_socket_type && !ntreetype->valid_socket_type(ntreetype, socket_type)) {
+ return false;
+ }
+
+ /* Only use basic socket types for this enum. */
+ if (socket_type->subtype != PROP_NONE) {
+ return false;
+ }
+
+ return true;
+}
+
+static const EnumPropertyItem *socket_change_type_itemf(bContext *C,
+ PointerRNA *UNUSED(ptr),
+ PropertyRNA *UNUSED(prop),
+ bool *r_free)
+{
+ if (!C) {
+ return DummyRNA_NULL_items;
+ }
+
+ SpaceNode *snode = CTX_wm_space_node(C);
+ if (!snode || !snode->edittree) {
+ return DummyRNA_NULL_items;
+ }
+
+ return rna_node_socket_type_itemf(snode->edittree->typeinfo, socket_change_poll_type, r_free);
+}
+
+void NODE_OT_tree_socket_change_type(wmOperatorType *ot)
+{
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Change Node Tree Interface Socket Type";
+ ot->description = "Change the type of a socket of the current node tree";
+ ot->idname = "NODE_OT_tree_socket_change_type";
+
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = ntree_socket_change_type_exec;
+ ot->poll = ED_operator_node_editable;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ RNA_def_enum(ot->srna, "in_out", rna_enum_node_socket_in_out_items, SOCK_IN, "Socket Type", "");
+ prop = RNA_def_enum(ot->srna, "socket_type", DummyRNA_DEFAULT_items, 0, "Socket Type", "");
+ RNA_def_enum_funcs(prop, socket_change_type_itemf);
+ ot->prop = prop;
+}
+
/********************** Move interface socket operator *********************/
static const EnumPropertyItem move_direction_items[] = {
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index e69f0cbea7f..fe550242dbe 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -296,6 +296,7 @@ void NODE_OT_clipboard_paste(struct wmOperatorType *ot);
void NODE_OT_tree_socket_add(struct wmOperatorType *ot);
void NODE_OT_tree_socket_remove(struct wmOperatorType *ot);
+void NODE_OT_tree_socket_change_type(struct wmOperatorType *ot);
void NODE_OT_tree_socket_move(struct wmOperatorType *ot);
void NODE_OT_shader_script_update(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c
index ce65fe93f20..610c2889e7a 100644
--- a/source/blender/editors/space_node/node_ops.c
+++ b/source/blender/editors/space_node/node_ops.c
@@ -119,6 +119,7 @@ void node_operatortypes(void)
WM_operatortype_append(NODE_OT_tree_socket_add);
WM_operatortype_append(NODE_OT_tree_socket_remove);
+ WM_operatortype_append(NODE_OT_tree_socket_change_type);
WM_operatortype_append(NODE_OT_tree_socket_move);
WM_operatortype_append(NODE_OT_cryptomatte_layer_add);
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 876229411e0..782d0924d21 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -450,6 +450,7 @@ extern StructRNA RNA_NodeOutputFileSlotFile;
extern StructRNA RNA_NodeOutputFileSlotLayer;
extern StructRNA RNA_NodeSocket;
extern StructRNA RNA_NodeSocketInterface;
+extern StructRNA RNA_NodeSocketStandard;
extern StructRNA RNA_NodeTree;
extern StructRNA RNA_NoiseGpencilModifier;
extern StructRNA RNA_NoiseTexture;
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 0a120837191..0afb9da9547 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -799,7 +799,7 @@ const EnumPropertyItem *rna_node_socket_type_itemf(void *data,
tmp.value = i;
tmp.identifier = stype->idname;
tmp.icon = RNA_struct_ui_icon(srna);
- tmp.name = RNA_struct_ui_name(srna);
+ tmp.name = nodeSocketTypeLabel(stype);
tmp.description = RNA_struct_ui_description(srna);
RNA_enum_item_add(&item, &totitem, &tmp);
@@ -1025,8 +1025,7 @@ static void rna_NodeTree_get_from_context(
RNA_parameter_list_free(&list);
}
-static bool rna_NodeTree_valid_socket_type(eNodeSocketDatatype socket_type,
- bNodeTreeType *ntreetype)
+static bool rna_NodeTree_valid_socket_type(bNodeTreeType *ntreetype, bNodeSocketType *socket_type)
{
extern FunctionRNA rna_NodeTree_valid_socket_type_func;
@@ -1040,7 +1039,7 @@ static bool rna_NodeTree_valid_socket_type(eNodeSocketDatatype socket_type,
func = &rna_NodeTree_valid_socket_type_func;
RNA_parameter_list_create(&list, &ptr, func);
- RNA_parameter_set_lookup(&list, "type", &socket_type);
+ RNA_parameter_set_lookup(&list, "idname", &socket_type->idname);
ntreetype->rna_ext.call(NULL, &ptr, func, &list);
RNA_parameter_get_lookup(&list, "valid", &ret);
@@ -2866,7 +2865,7 @@ static void rna_NodeSocket_type_set(PointerRNA *ptr, int value)
bNodeSocket *sock = (bNodeSocket *)ptr->data;
bNode *node;
nodeFindNode(ntree, sock, &node, NULL);
- nodeModifySocketType(ntree, node, sock, value, 0);
+ nodeModifySocketTypeStatic(ntree, node, sock, value, 0);
}
static void rna_NodeSocket_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
@@ -10176,7 +10175,7 @@ static void rna_def_node_socket(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Node Socket", "Input or output socket of a node");
RNA_def_struct_sdna(srna, "bNodeSocket");
RNA_def_struct_refine_func(srna, "rna_NodeSocket_refine");
- RNA_def_struct_ui_icon(srna, ICON_PLUGIN);
+ RNA_def_struct_ui_icon(srna, ICON_NONE);
RNA_def_struct_path_func(srna, "rna_NodeSocket_path");
RNA_def_struct_register_funcs(
srna, "rna_NodeSocket_register", "rna_NodeSocket_unregister", NULL);
@@ -10281,6 +10280,11 @@ static void rna_def_node_socket(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_REGISTER);
RNA_def_property_ui_text(prop, "ID Name", "");
+ prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "typeinfo->label");
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+ RNA_def_property_ui_text(prop, "Type Label", "Label to display for the socket type in the UI");
+
/* draw socket */
func = RNA_def_function(srna, "draw", NULL);
RNA_def_function_ui_description(func, "Draw socket");
@@ -10369,6 +10373,11 @@ static void rna_def_node_socket_interface(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_REGISTER);
RNA_def_property_ui_text(prop, "ID Name", "");
+ prop = RNA_def_property(srna, "bl_label", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "typeinfo->label");
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+ RNA_def_property_ui_text(prop, "Type Label", "Label to display for the socket type in the UI");
+
func = RNA_def_function(srna, "draw", NULL);
RNA_def_function_ui_description(func, "Draw template settings");
RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL);
@@ -11879,11 +11888,12 @@ static void rna_def_nodetree(BlenderRNA *brna)
func, "result_3", "ID", "From ID", "Original ID data-block selected from the context");
RNA_def_function_output(func, parm);
- /* Check for support of a socket type. */
+ /* Check for support of a socket type with a type identifier. */
func = RNA_def_function(srna, "valid_socket_type", NULL);
RNA_def_function_ui_description(func, "Check if the socket type is valid for the node tree");
RNA_def_function_flag(func, FUNC_NO_SELF | FUNC_REGISTER_OPTIONAL);
- parm = RNA_def_enum(func, "type", node_socket_type_items, 0, "", "");
+ parm = RNA_def_string(
+ func, "idname", "NodeSocket", MAX_NAME, "Socket Type", "Identifier of the socket type");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
RNA_def_function_return(func, RNA_def_boolean(func, "valid", false, "", ""));
}
diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c
index 19815d01278..013d196e1c8 100644
--- a/source/blender/nodes/composite/node_composite_tree.c
+++ b/source/blender/nodes/composite/node_composite_tree.c
@@ -205,10 +205,11 @@ static void composite_node_add_init(bNodeTree *UNUSED(bnodetree), bNode *bnode)
}
}
-static bool composite_node_tree_socket_type_valid(eNodeSocketDatatype socket_type,
- bNodeTreeType *UNUSED(ntreetype))
+static bool composite_node_tree_socket_type_valid(bNodeTreeType *UNUSED(ntreetype),
+ bNodeSocketType *socket_type)
{
- return ELEM(socket_type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA);
+ return nodeIsStaticSocketType(socket_type) &&
+ ELEM(socket_type->type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA);
}
bNodeTreeType *ntreeType_Composite;
diff --git a/source/blender/nodes/geometry/node_geometry_tree.cc b/source/blender/nodes/geometry/node_geometry_tree.cc
index f4cd00b88ed..07a89a1fa8c 100644
--- a/source/blender/nodes/geometry/node_geometry_tree.cc
+++ b/source/blender/nodes/geometry/node_geometry_tree.cc
@@ -95,21 +95,21 @@ static bool geometry_node_tree_validate_link(bNodeTree *UNUSED(ntree), bNodeLink
return (link->tosock->type == link->fromsock->type);
}
-static bool geometry_node_tree_socket_type_valid(eNodeSocketDatatype socket_type,
- bNodeTreeType *UNUSED(ntreetype))
+static bool geometry_node_tree_socket_type_valid(bNodeTreeType *UNUSED(ntreetype),
+ bNodeSocketType *socket_type)
{
- return ELEM(socket_type,
- SOCK_FLOAT,
- SOCK_VECTOR,
- SOCK_RGBA,
- SOCK_BOOLEAN,
- SOCK_INT,
- SOCK_STRING,
- SOCK_OBJECT,
- SOCK_GEOMETRY,
- SOCK_COLLECTION,
- SOCK_TEXTURE,
- SOCK_MATERIAL);
+ return nodeIsStaticSocketType(socket_type) && ELEM(socket_type->type,
+ SOCK_FLOAT,
+ SOCK_VECTOR,
+ SOCK_RGBA,
+ SOCK_BOOLEAN,
+ SOCK_INT,
+ SOCK_STRING,
+ SOCK_OBJECT,
+ SOCK_GEOMETRY,
+ SOCK_COLLECTION,
+ SOCK_TEXTURE,
+ SOCK_MATERIAL);
}
void register_node_tree_type_geo(void)
diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c
index fe11318c29d..b8c89d1db37 100644
--- a/source/blender/nodes/intern/node_common.c
+++ b/source/blender/nodes/intern/node_common.c
@@ -127,7 +127,7 @@ static bNodeSocket *group_verify_socket(
bNodeSocket *sock;
for (sock = verify_lb->first; sock; sock = sock->next) {
- if (sock->typeinfo == iosock->typeinfo && STREQ(sock->identifier, iosock->identifier)) {
+ if (STREQ(sock->identifier, iosock->identifier)) {
break;
}
}
@@ -137,6 +137,13 @@ static bNodeSocket *group_verify_socket(
const int mask = SOCK_HIDE_VALUE;
sock->flag = (sock->flag & ~mask) | (iosock->flag & mask);
+ /* Update socket type if necessary */
+ if (sock->typeinfo != iosock->typeinfo) {
+ nodeModifySocketType(ntree, gnode, sock, iosock->idname);
+ /* Flag the tree to make sure link validity is updated after type changes. */
+ ntree->update |= NTREE_UPDATE_LINKS;
+ }
+
if (iosock->typeinfo->interface_verify_socket) {
iosock->typeinfo->interface_verify_socket(ntree, iosock, gnode, sock, "interface");
}
diff --git a/source/blender/nodes/intern/node_socket.cc b/source/blender/nodes/intern/node_socket.cc
index 9f0a145ace2..8fdad0bb242 100644
--- a/source/blender/nodes/intern/node_socket.cc
+++ b/source/blender/nodes/intern/node_socket.cc
@@ -117,7 +117,7 @@ static bNodeSocket *verify_socket_template(bNodeTree *ntree,
}
if (sock) {
if (sock->type != stemp->type) {
- nodeModifySocketType(ntree, node, sock, stemp->type, stemp->subtype);
+ nodeModifySocketTypeStatic(ntree, node, sock, stemp->type, stemp->subtype);
}
sock->flag |= stemp->flag;
}
@@ -533,12 +533,14 @@ static bNodeSocketType *make_standard_socket_type(int type, int subtype)
{
const char *socket_idname = nodeStaticSocketType(type, subtype);
const char *interface_idname = nodeStaticSocketInterfaceType(type, subtype);
+ const char *socket_label = nodeStaticSocketLabel(type, subtype);
bNodeSocketType *stype;
StructRNA *srna;
stype = (bNodeSocketType *)MEM_callocN(sizeof(bNodeSocketType), "node socket C type");
stype->free_self = (void (*)(bNodeSocketType * stype)) MEM_freeN;
BLI_strncpy(stype->idname, socket_idname, sizeof(stype->idname));
+ BLI_strncpy(stype->label, socket_label, sizeof(stype->label));
/* set the RNA type
* uses the exact same identifier as the socket type idname */
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index 9bf07392c11..7367f73d171 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -184,10 +184,11 @@ static bool shader_validate_link(bNodeTree *UNUSED(ntree), bNodeLink *link)
return true;
}
-static bool shader_node_tree_socket_type_valid(eNodeSocketDatatype socket_type,
- bNodeTreeType *UNUSED(ntreetype))
+static bool shader_node_tree_socket_type_valid(bNodeTreeType *UNUSED(ntreetype),
+ bNodeSocketType *socket_type)
{
- return ELEM(socket_type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_SHADER);
+ return nodeIsStaticSocketType(socket_type) &&
+ ELEM(socket_type->type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA, SOCK_SHADER);
}
bNodeTreeType *ntreeType_Shader;
diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c
index 2ae722e3cd8..f771b4934b2 100644
--- a/source/blender/nodes/texture/node_texture_tree.c
+++ b/source/blender/nodes/texture/node_texture_tree.c
@@ -152,10 +152,11 @@ static void update(bNodeTree *ntree)
}
}
-static bool texture_node_tree_socket_type_valid(eNodeSocketDatatype socket_type,
- bNodeTreeType *UNUSED(ntreetype))
+static bool texture_node_tree_socket_type_valid(bNodeTreeType *UNUSED(ntreetype),
+ bNodeSocketType *socket_type)
{
- return ELEM(socket_type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA);
+ return nodeIsStaticSocketType(socket_type) &&
+ ELEM(socket_type->type, SOCK_FLOAT, SOCK_VECTOR, SOCK_RGBA);
}
bNodeTreeType *ntreeType_Texture;