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 /source/blender/editors
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
Diffstat (limited to 'source/blender/editors')
-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
4 files changed, 134 insertions, 2 deletions
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);