From 0e09075e39569f6792d72fd53330bf9618283ea1 Mon Sep 17 00:00:00 2001 From: Alexander Gavrilov Date: Sat, 11 May 2019 17:53:17 +0300 Subject: Fix T59627: missing COW update tags when joining armatures. Objects that had constraints or drivers referring to the joined armatures weren't tagged, and thus evaluated copies ended up with old bad pointers. --- .../blender/editors/armature/armature_relations.c | 37 +++++++++++++++++++--- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'source/blender/editors/armature/armature_relations.c') diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c index b2ca1d84520..2c61818d902 100644 --- a/source/blender/editors/armature/armature_relations.c +++ b/source/blender/editors/armature/armature_relations.c @@ -66,10 +66,16 @@ /* *************************************** Join *************************************** */ /* NOTE: no operator define here as this is exported to the Object-level operator */ -static void joined_armature_fix_links_constraints( - Object *tarArm, Object *srcArm, bPoseChannel *pchan, EditBone *curbone, ListBase *lb) +static void joined_armature_fix_links_constraints(Main *bmain, + Object *ob, + Object *tarArm, + Object *srcArm, + bPoseChannel *pchan, + EditBone *curbone, + ListBase *lb) { bConstraint *con; + bool changed = false; for (con = lb->first; con; con = con->next) { const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); @@ -84,10 +90,12 @@ static void joined_armature_fix_links_constraints( if (ct->tar == srcArm) { if (ct->subtarget[0] == '\0') { ct->tar = tarArm; + changed = true; } else if (STREQ(ct->subtarget, pchan->name)) { ct->tar = tarArm; BLI_strncpy(ct->subtarget, curbone->name, sizeof(ct->subtarget)); + changed = true; } } } @@ -104,13 +112,21 @@ static void joined_armature_fix_links_constraints( if (data->act) { BKE_action_fix_paths_rename( &tarArm->id, data->act, "pose.bones[", pchan->name, curbone->name, 0, 0, false); + + DEG_id_tag_update_ex(bmain, &data->act->id, ID_RECALC_COPY_ON_WRITE); } } } + + if (changed) { + DEG_id_tag_update_ex(bmain, &ob->id, ID_RECALC_COPY_ON_WRITE); + } } /* userdata for joined_armature_fix_animdata_cb() */ typedef struct tJoinArmature_AdtFixData { + Main *bmain; + Object *srcArm; Object *tarArm; @@ -129,6 +145,7 @@ static void joined_armature_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data ID *dst_id = &afd->tarArm->id; GHashIterator gh_iter; + bool changed = false; /* Fix paths - If this is the target object, it will have some "dirty" paths */ if ((id == src_id) && strstr(fcu->rna_path, "pose.bones[")) { @@ -142,6 +159,8 @@ static void joined_armature_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data fcu->rna_path = BKE_animsys_fix_rna_path_rename( id, fcu->rna_path, "pose.bones", old_name, new_name, 0, 0, false); + changed = true; + /* we don't want to apply a second remapping on this driver now, * so stop trying names, but keep fixing drivers */ @@ -163,6 +182,8 @@ static void joined_armature_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data if (dtar->id == src_id) { dtar->id = dst_id; + changed = true; + /* also check on the subtarget... * XXX: We duplicate the logic from drivers_path_rename_fix() here, with our own * little twists so that we know that it isn't going to clobber the wrong data @@ -193,6 +214,10 @@ static void joined_armature_fix_animdata_cb(ID *id, FCurve *fcu, void *user_data DRIVER_TARGETS_LOOPER_END; } } + + if (changed) { + DEG_id_tag_update_ex(afd->bmain, id, ID_RECALC_COPY_ON_WRITE); + } } /* Helper function for armature joining - link fixing */ @@ -210,13 +235,14 @@ static void joined_armature_fix_links( pose = ob->pose; for (pchant = pose->chanbase.first; pchant; pchant = pchant->next) { joined_armature_fix_links_constraints( - tarArm, srcArm, pchan, curbone, &pchant->constraints); + bmain, ob, tarArm, srcArm, pchan, curbone, &pchant->constraints); } } /* fix object-level constraints */ if (ob != srcArm) { - joined_armature_fix_links_constraints(tarArm, srcArm, pchan, curbone, &ob->constraints); + joined_armature_fix_links_constraints( + bmain, ob, tarArm, srcArm, pchan, curbone, &ob->constraints); } /* See if an object is parented to this armature */ @@ -231,6 +257,8 @@ static void joined_armature_fix_links( /* make tar armature be new parent */ ob->parent = tarArm; + + DEG_id_tag_update_ex(bmain, &ob->id, ID_RECALC_COPY_ON_WRITE); } } } @@ -286,6 +314,7 @@ int join_armature_exec(bContext *C, wmOperator *op) BLI_assert(ob_active->data != ob_iter->data); /* init callback data for fixing up AnimData links later */ + afd.bmain = bmain; afd.srcArm = ob_iter; afd.tarArm = ob_active; afd.names_map = BLI_ghash_str_new("join_armature_adt_fix"); -- cgit v1.2.3