diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2018-07-19 17:48:21 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2018-07-20 11:22:06 +0300 |
commit | c205de020365eddbbc0f0cde0ad02dda91126807 (patch) | |
tree | 7358cf5ace428f2fccff43e25d8c5f091eab87a7 /source/blender/blenkernel/intern/armature.c | |
parent | 8a42b3909f33d90b065eec2b8eb342df0a1fb659 (diff) |
Fix T55973: [2.8] Crash when 'apply pose as rest pose' when bone scale is 0,0,0.
`BKE_pose_rebuild()` should (ideally) always trigger a rebuild of the
depsgraph, since it can add or remove posechannels.
This function now takes a Main parameter to ensure that related
depsgraphes are tagged as dirty (kept it optional, for some corner cases).
We should also probably double-check calls to that function, think in
theory it should only be called from depsgraph itself? But for now...
Diffstat (limited to 'source/blender/blenkernel/intern/armature.c')
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index bd9ee7c9e5f..6be4574a62e 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -71,6 +71,8 @@ #include "BKE_object.h" #include "BKE_scene.h" +#include "DEG_depsgraph_build.h" + #include "BIK_api.h" /* **************** Generic Functions, data level *************** */ @@ -1951,9 +1953,14 @@ void BKE_pose_remap_bone_pointers(bArmature *armature, bPose *pose) BLI_ghash_free(bone_hash, NULL, NULL); } -/* only after leave editmode, duplicating, validating older files, library syncing */ -/* NOTE: pose->flag is set for it */ -void BKE_pose_rebuild(Object *ob, bArmature *arm) +/** + * Only after leave editmode, duplicating, validating older files, library syncing. + * + * \note pose->flag is set for it. + * + * \param bmain May be NULL, only used to tag depsgraph as being dirty... + */ +void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm) { Bone *bone; bPose *pose; @@ -1998,12 +2005,17 @@ void BKE_pose_rebuild(Object *ob, bArmature *arm) pose_proxy_synchronize(ob, ob->proxy, arm->layer_protected); } - BKE_pose_update_constraint_flags(ob->pose); /* for IK detection for example */ + BKE_pose_update_constraint_flags(pose); /* for IK detection for example */ + + pose->flag &= ~POSE_RECALC; + pose->flag |= POSE_WAS_REBUILT; - ob->pose->flag &= ~POSE_RECALC; - ob->pose->flag |= POSE_WAS_REBUILT; + BKE_pose_channels_hash_make(pose); - BKE_pose_channels_hash_make(ob->pose); + /* Rebuilding poses forces us to also rebuild the dependency graph, since there is one node per pose/bone... */ + if (bmain != NULL) { + DEG_relations_tag_update(bmain); + } } /* ********************** THE POSE SOLVER ******************* */ @@ -2277,8 +2289,10 @@ void BKE_pose_where_is(struct Depsgraph *depsgraph, Scene *scene, Object *ob) if (ELEM(NULL, arm, scene)) return; - if ((ob->pose == NULL) || (ob->pose->flag & POSE_RECALC)) - BKE_pose_rebuild(ob, arm); + 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); + } ctime = BKE_scene_frame_get(scene); /* not accurate... */ |