Respect ID user count when creating pose on object copy

This solves wrong user counter of custom shape when duplicating bone
few times and then undoing all the duplications.
This commit is contained in:
Sergey Sharybin 2018-07-31 11:38:10 +02:00
parent 75f1fb6d86
commit 1fd27c2332
Notes: blender-bot 2023-02-14 07:39:46 +01:00
Referenced by issue #56170, Fake dependency cycle in new depsgraph + interleaved armature update + proxy
10 changed files with 17 additions and 15 deletions

View File

@ -100,7 +100,7 @@ void BKE_armature_where_is(struct bArmature *arm);
void BKE_armature_where_is_bone(struct Bone *bone, struct Bone *prevbone, const bool use_recursion);
void BKE_pose_clear_pointers(struct bPose *pose);
void BKE_pose_remap_bone_pointers(struct bArmature *armature, struct bPose *pose);
void BKE_pose_rebuild(struct Main *bmain, struct Object *ob, struct bArmature *arm);
void BKE_pose_rebuild(struct Main *bmain, struct Object *ob, struct bArmature *arm, const bool do_id_user);
void BKE_pose_where_is(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
void BKE_pose_where_is_bone(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime, bool do_extra);
void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan);

View File

@ -1960,7 +1960,7 @@ void BKE_pose_remap_bone_pointers(bArmature *armature, bPose *pose)
*
* \param bmain May be NULL, only used to tag depsgraph as being dirty...
*/
void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm)
void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, const bool do_id_user)
{
Bone *bone;
bPose *pose;
@ -1989,7 +1989,7 @@ void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm)
for (pchan = pose->chanbase.first; pchan; pchan = next) {
next = pchan->next;
if (pchan->bone == NULL) {
BKE_pose_channel_free(pchan);
BKE_pose_channel_free_ex(pchan, do_id_user);
BKE_pose_channels_hash_free(pose);
BLI_freelinkN(&pose->chanbase, pchan);
}
@ -2291,7 +2291,7 @@ void BKE_pose_where_is(struct Depsgraph *depsgraph, Scene *scene, Object *ob)
return;
if ((ob->pose == NULL) || (ob->pose->flag & POSE_RECALC)) {
/* WARNING! passing NULL bmain here means we won't tag depsgraph's as dirty - hopefully this is OK. */
BKE_pose_rebuild(NULL, ob, arm);
BKE_pose_rebuild(NULL, ob, arm, true);
}
ctime = BKE_scene_frame_get(scene); /* not accurate... */

View File

@ -2465,7 +2465,7 @@ void BKE_library_make_local(
* Try "make all local" in 04_01_H.lighting.blend from Agent327 without this, e.g. */
for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->data != NULL && ob->type == OB_ARMATURE && ob->pose != NULL && ob->pose->flag & POSE_RECALC) {
BKE_pose_rebuild(bmain, ob, ob->data);
BKE_pose_rebuild(bmain, ob, ob->data, true);
}
}

View File

@ -1281,8 +1281,10 @@ void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, con
if (ob_src->pose) {
copy_object_pose(ob_dst, ob_src, flag_subdata);
/* backwards compat... non-armatures can get poses in older files? */
if (ob_src->type == OB_ARMATURE)
BKE_pose_rebuild(bmain, ob_dst, ob_dst->data);
if (ob_src->type == OB_ARMATURE) {
const bool do_pose_id_user = (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0;
BKE_pose_rebuild(bmain, ob_dst, ob_dst->data, do_pose_id_user);
}
}
defgroup_copy_list(&ob_dst->defbase, &ob_src->defbase);
BKE_object_facemap_copy_list(&ob_dst->fmaps, &ob_src->fmaps);
@ -1536,7 +1538,7 @@ void BKE_object_make_proxy(Main *bmain, Object *ob, Object *target, Object *cob)
if (target->type == OB_ARMATURE) {
copy_object_pose(ob, target, 0); /* data copy, object pointers in constraints */
BKE_pose_rest(ob->pose); /* clear all transforms in channels */
BKE_pose_rebuild(bmain, ob, ob->data); /* set all internal links */
BKE_pose_rebuild(bmain, ob, ob->data, true); /* set all internal links */
armature_set_id_extern(ob);
}
@ -2807,7 +2809,7 @@ void BKE_object_handle_update_ex(Depsgraph *depsgraph,
* on file load */
if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) {
/* No need to pass bmain here, we assume we do not need to rebuild DEG from here... */
BKE_pose_rebuild(NULL, ob, ob->data);
BKE_pose_rebuild(NULL, ob, ob->data, true);
}
}
}

View File

@ -1336,7 +1336,7 @@ static void scene_armature_depsgraph_workaround(Main *bmain, Depsgraph *depsgrap
for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->type == OB_ARMATURE && ob->adt && ob->adt->recalc & ADT_RECALC_ANIM) {
if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC)) {
BKE_pose_rebuild(bmain, ob, ob->data);
BKE_pose_rebuild(bmain, ob, ob->data, true);
}
}
}

View File

@ -162,7 +162,7 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
/* Rebuild pose if not up to date. */
if (object->pose == NULL || (object->pose->flag & POSE_RECALC)) {
/* By definition, no need to tag depsgraph as dirty from here, so we can pass NULL bmain. */
BKE_pose_rebuild(NULL, object, armature);
BKE_pose_rebuild(NULL, object, armature, true);
/* XXX: Without this animation gets lost in certain circumstances
* after loading file. Need to investigate further since it does
* not happen with simple scenes..

View File

@ -681,7 +681,7 @@ void ED_armature_from_edit(Main *bmain, bArmature *arm)
/* so all users of this armature should get rebuilt */
for (obt = bmain->object.first; obt; obt = obt->id.next) {
if (obt->data == arm) {
BKE_pose_rebuild(bmain, obt, arm);
BKE_pose_rebuild(bmain, obt, arm, true);
}
}

View File

@ -2332,7 +2332,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, ViewLayer
ID_NEW_REMAP_US2(obn->data)
else {
obn->data = ID_NEW_SET(obn->data, BKE_armature_copy(bmain, obn->data));
BKE_pose_rebuild(bmain, obn, obn->data);
BKE_pose_rebuild(bmain, obn, obn->data, true);
didit = 1;
}
id_us_min(id);

View File

@ -1789,7 +1789,7 @@ static void single_obdata_users(Main *bmain, Scene *scene, ViewLayer *view_layer
case OB_ARMATURE:
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
ob->data = ID_NEW_SET(ob->data, BKE_armature_copy(bmain, ob->data));
BKE_pose_rebuild(bmain, ob, ob->data);
BKE_pose_rebuild(bmain, ob, ob->data, true);
break;
case OB_SPEAKER:
ob->data = ID_NEW_SET(ob->data, BKE_speaker_copy(bmain, ob->data));

View File

@ -372,7 +372,7 @@ static void rna_Object_data_set(PointerRNA *ptr, PointerRNA value)
BKE_curve_type_test(ob);
}
else if (ob->type == OB_ARMATURE) {
BKE_pose_rebuild(G_MAIN, ob, ob->data);
BKE_pose_rebuild(G_MAIN, ob, ob->data, true);
}
}
}