Fix T94559: Copying geometry node group does not copy animation data

Reimplement copy geometry node groups in C. The version implemented in
Python could also manually copy the animation data, but it's more
standard to do this with `BKE_id_copy_ex` and `LIB_ID_COPY_ACTIONS`.

Differential Revision: https://developer.blender.org/D14615
This commit is contained in:
Angus Stanton 2022-04-18 10:15:30 -05:00 committed by Hans Goudey
parent ef2b8c1c3a
commit ccd2e89d37
Notes: blender-bot 2023-02-14 07:39:44 +01:00
Referenced by issue #100980, Geometry nodes tree still uses the animation of the original node tree where it was copied from
Referenced by issue #98316, Regression: Geometry Node Tree Stop Update Upon Duplication
Referenced by issue #97747, Duplicate of Geometry Node system sharing animation channel
Referenced by issue #94559, Geometry nodes: keyframes being deleted if you delete the same node in a node tree duplicate
5 changed files with 50 additions and 26 deletions

View File

@ -83,32 +83,7 @@ class NewGeometryNodeTreeAssign(Operator):
return {'FINISHED'}
class CopyGeometryNodeTreeAssign(Operator):
"""Copy the active geometry node group and assign it to the active modifier"""
bl_idname = "node.copy_geometry_node_group_assign"
bl_label = "Copy Geometry Node Group"
bl_options = {'REGISTER', 'UNDO'}
@classmethod
def poll(cls, context):
return geometry_modifier_poll(context)
def execute(self, context):
modifier = context.object.modifiers.active
if modifier is None:
return {'CANCELLED'}
group = modifier.node_group
if group is None:
return {'CANCELLED'}
modifier.node_group = group.copy()
return {'FINISHED'}
classes = (
NewGeometryNodesModifier,
NewGeometryNodeTreeAssign,
CopyGeometryNodeTreeAssign,
)

View File

@ -149,7 +149,7 @@ class NODE_HT_header(Header):
active_modifier = ob.modifiers.active
if active_modifier and active_modifier.type == 'NODES':
if active_modifier.node_group:
row.template_ID(active_modifier, "node_group", new="node.copy_geometry_node_group_assign")
row.template_ID(active_modifier, "node_group", new="object.geometry_node_tree_copy_assign")
else:
row.template_ID(active_modifier, "node_group", new="node.new_geometry_node_group_assign")
else:

View File

@ -201,6 +201,7 @@ void OBJECT_OT_skin_armature_create(struct wmOperatorType *ot);
void OBJECT_OT_laplaciandeform_bind(struct wmOperatorType *ot);
void OBJECT_OT_surfacedeform_bind(struct wmOperatorType *ot);
void OBJECT_OT_geometry_nodes_input_attribute_toggle(struct wmOperatorType *ot);
void OBJECT_OT_geometry_node_tree_copy_assign(struct wmOperatorType *ot);
/* object_gpencil_modifiers.c */

View File

@ -3293,3 +3293,50 @@ void OBJECT_OT_geometry_nodes_input_attribute_toggle(wmOperatorType *ot)
}
/** \} */
/* ------------------------------------------------------------------- */
/** \name Copy and Assign Geometry Node Group operator
* \{ */
static int geometry_node_tree_copy_assign_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Object *ob = ED_object_active_context(C);
ModifierData *md = BKE_object_active_modifier(ob);
if (md->type != eModifierType_Nodes) {
return OPERATOR_CANCELLED;
}
NodesModifierData *nmd = (NodesModifierData *)md;
bNodeTree *tree = nmd->node_group;
if (tree == NULL) {
return OPERATOR_CANCELLED;
}
bNodeTree *new_tree = (bNodeTree *)BKE_id_copy_ex(
bmain, &tree->id, NULL, LIB_ID_COPY_ACTIONS | LIB_ID_COPY_DEFAULT);
if (new_tree == NULL) {
return OPERATOR_CANCELLED;
}
nmd->node_group = new_tree;
id_us_min(&tree->id);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
return OPERATOR_FINISHED;
}
void OBJECT_OT_geometry_node_tree_copy_assign(wmOperatorType *ot)
{
ot->name = "Copy Geometry Node Group";
ot->description = "Copy the active geometry node group and assign it to the active modifier";
ot->idname = "OBJECT_OT_geometry_node_tree_copy_assign";
ot->exec = geometry_node_tree_copy_assign_exec;
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/** \} */

View File

@ -133,6 +133,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_skin_radii_equalize);
WM_operatortype_append(OBJECT_OT_skin_armature_create);
WM_operatortype_append(OBJECT_OT_geometry_nodes_input_attribute_toggle);
WM_operatortype_append(OBJECT_OT_geometry_node_tree_copy_assign);
/* grease pencil modifiers */
WM_operatortype_append(OBJECT_OT_gpencil_modifier_add);