Nodes: Duplicate Linked operator + User Preference option for Node Tree
This operator (Alt + D) allows users to explicitly create a linked copy of a group node (same current behaviour for the Duplicate operator). The duplicate operator (Shift + D) now takes the new User Preference duplicate data option for Node Tree into account. It is by default disabled, leading to no functional change for users. Although we could make in the future make this option "on" by default, to make it consistent with the rest of Blender we do not at the time. Differential Revision: https://developer.blender.org/D16210
This commit is contained in:
parent
a5d3b648e3
commit
6beeba1ef5
Notes:
blender-bot
2023-02-14 08:42:53 +01:00
Referenced by issue #102864, Regression: delete with reconnect not working properly in the node editor Referenced by issue #102864, Regression: delete with reconnect not working properly in the node editor Referenced by issue #102276, Hotkey conflict Alt D in Node Editor with Duplicate Linked and Detach
|
@ -2073,6 +2073,8 @@ def km_node_editor(params):
|
|||
op_menu("NODE_MT_add", {"type": 'A', "value": 'PRESS', "shift": True}),
|
||||
("node.duplicate_move", {"type": 'D', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("NODE_OT_translate_attach", [("TRANSFORM_OT_translate", [("view2d_edge_pan", True)])])]}),
|
||||
("node.duplicate_move_linked", {"type": 'D', "value": 'PRESS', "alt": True},
|
||||
{"properties": [("NODE_OT_translate_attach", [("TRANSFORM_OT_translate", [("view2d_edge_pan", True)])])]}),
|
||||
("node.duplicate_move_keep_inputs", {"type": 'D', "value": 'PRESS', "shift": True, "ctrl": True},
|
||||
{"properties": [("NODE_OT_translate_attach", [("TRANSFORM_OT_translate", [("view2d_edge_pan", True)])])]}),
|
||||
("node.parent_set", {"type": 'P', "value": 'PRESS', "ctrl": True}, None),
|
||||
|
|
|
@ -318,6 +318,7 @@ class NODE_MT_node(Menu):
|
|||
layout.operator("node.clipboard_copy", text="Copy")
|
||||
layout.operator("node.clipboard_paste", text="Paste")
|
||||
layout.operator("node.duplicate_move")
|
||||
layout.operator("node.duplicate_move_linked")
|
||||
layout.operator("node.delete")
|
||||
layout.operator("node.delete_reconnect")
|
||||
|
||||
|
|
|
@ -397,17 +397,18 @@ class USERPREF_PT_edit_objects_duplicate_data(EditingPanel, CenterAlignMixIn, Pa
|
|||
# col.prop(edit, "use_duplicate_fcurve", text="F-Curve") # Not implemented.
|
||||
col.prop(edit, "use_duplicate_curves", text="Curves")
|
||||
col.prop(edit, "use_duplicate_grease_pencil", text="Grease Pencil")
|
||||
col.prop(edit, "use_duplicate_lattice", text="Lattice")
|
||||
|
||||
col = flow.column()
|
||||
col.prop(edit, "use_duplicate_lattice", text="Lattice")
|
||||
col.prop(edit, "use_duplicate_light", text="Light")
|
||||
col.prop(edit, "use_duplicate_lightprobe", text="Light Probe")
|
||||
col.prop(edit, "use_duplicate_material", text="Material")
|
||||
col.prop(edit, "use_duplicate_mesh", text="Mesh")
|
||||
col.prop(edit, "use_duplicate_metaball", text="Metaball")
|
||||
col.prop(edit, "use_duplicate_node_tree", text="Node Tree")
|
||||
col.prop(edit, "use_duplicate_particle", text="Particle")
|
||||
|
||||
col = flow.column()
|
||||
col.prop(edit, "use_duplicate_particle", text="Particle")
|
||||
if hasattr(edit, "use_duplicate_pointcloud"):
|
||||
col.prop(edit, "use_duplicate_pointcloud", text="Point Cloud")
|
||||
col.prop(edit, "use_duplicate_speaker", text="Speaker")
|
||||
|
|
|
@ -1361,12 +1361,15 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
|
|||
SpaceNode *snode = CTX_wm_space_node(C);
|
||||
bNodeTree *ntree = snode->edittree;
|
||||
const bool keep_inputs = RNA_boolean_get(op->ptr, "keep_inputs");
|
||||
bool linked = RNA_boolean_get(op->ptr, "linked") || ((U.dupflag & USER_DUP_NTREE) == 0);
|
||||
const bool dupli_node_tree = !linked;
|
||||
bool changed = false;
|
||||
|
||||
ED_preview_kill_jobs(CTX_wm_manager(C), bmain);
|
||||
|
||||
Map<const bNode *, bNode *> node_map;
|
||||
Map<const bNodeSocket *, bNodeSocket *> socket_map;
|
||||
Map<const ID *, ID *> duplicated_node_groups;
|
||||
|
||||
bNode *lastnode = (bNode *)ntree->nodes.last;
|
||||
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
|
||||
|
@ -1374,6 +1377,18 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
|
|||
bNode *new_node = bke::node_copy_with_mapping(
|
||||
ntree, *node, LIB_ID_COPY_DEFAULT, true, socket_map);
|
||||
node_map.add_new(node, new_node);
|
||||
|
||||
if (node->id && dupli_node_tree) {
|
||||
ID *new_group = duplicated_node_groups.lookup_or_add_cb(node->id, [&]() {
|
||||
ID *new_group = BKE_id_copy(bmain, node->id);
|
||||
/* Remove user added by copying. */
|
||||
id_us_min(new_group);
|
||||
return new_group;
|
||||
});
|
||||
id_us_plus(new_group);
|
||||
id_us_min(new_node->id);
|
||||
new_node->id = new_group;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
|
||||
|
@ -1462,6 +1477,8 @@ static int node_duplicate_exec(bContext *C, wmOperator *op)
|
|||
|
||||
void NODE_OT_duplicate(wmOperatorType *ot)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "Duplicate Nodes";
|
||||
ot->description = "Duplicate selected nodes";
|
||||
|
@ -1476,6 +1493,13 @@ void NODE_OT_duplicate(wmOperatorType *ot)
|
|||
|
||||
RNA_def_boolean(
|
||||
ot->srna, "keep_inputs", false, "Keep Inputs", "Keep the input links to duplicated nodes");
|
||||
|
||||
prop = RNA_def_boolean(ot->srna,
|
||||
"linked",
|
||||
true,
|
||||
"Linked",
|
||||
"Duplicate node but not node trees, linking to the original data");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
/* XXX: some code needing updating to operators. */
|
||||
|
|
|
@ -174,7 +174,17 @@ void ED_operatormacros_node()
|
|||
"Duplicate",
|
||||
"Duplicate selected nodes and move them",
|
||||
OPTYPE_UNDO | OPTYPE_REGISTER);
|
||||
WM_operatortype_macro_define(ot, "NODE_OT_duplicate");
|
||||
mot = WM_operatortype_macro_define(ot, "NODE_OT_duplicate");
|
||||
RNA_boolean_set(mot->ptr, "linked", false);
|
||||
WM_operatortype_macro_define(ot, "NODE_OT_translate_attach");
|
||||
|
||||
ot = WM_operatortype_append_macro(
|
||||
"NODE_OT_duplicate_move_linked",
|
||||
"Duplicate Linked",
|
||||
"Duplicate selected nodes, but not their node trees, and move them",
|
||||
OPTYPE_UNDO | OPTYPE_REGISTER);
|
||||
mot = WM_operatortype_macro_define(ot, "NODE_OT_duplicate");
|
||||
RNA_boolean_set(mot->ptr, "linked", true);
|
||||
WM_operatortype_macro_define(ot, "NODE_OT_translate_attach");
|
||||
|
||||
/* modified operator call for duplicating with input links */
|
||||
|
|
|
@ -39,6 +39,7 @@ typedef enum eDupli_ID_Flags {
|
|||
USER_DUP_LATTICE = (1 << 17),
|
||||
USER_DUP_CAMERA = (1 << 18),
|
||||
USER_DUP_SPEAKER = (1 << 19),
|
||||
USER_DUP_NTREE = (1 << 20),
|
||||
|
||||
USER_DUP_OBDATA = (~0) & ((1 << 24) - 1),
|
||||
|
||||
|
|
|
@ -5232,6 +5232,12 @@ static void rna_def_userdef_edit(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(
|
||||
prop, "Duplicate Volume", "Causes volume data to be duplicated with the object");
|
||||
|
||||
prop = RNA_def_property(srna, "use_duplicate_node_tree", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "dupflag", USER_DUP_NTREE);
|
||||
RNA_def_property_ui_text(prop,
|
||||
"Duplicate Node Tree",
|
||||
"Make copies of node groups when duplicating nodes in the node editor");
|
||||
|
||||
/* Currently only used for insert offset (aka auto-offset),
|
||||
* maybe also be useful for later stuff though. */
|
||||
prop = RNA_def_property(srna, "node_margin", PROP_INT, PROP_PIXEL);
|
||||
|
|
Loading…
Reference in New Issue