forked from bartvdbraak/blender
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.
This commit is contained in:
parent
5f84e2d732
commit
0e09075e39
@ -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");
|
||||
|
Loading…
Reference in New Issue
Block a user