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...
This commit is contained in:
parent
8a42b3909f
commit
c205de0203
Notes:
blender-bot
2023-02-14 10:37:50 +01:00
Referenced by issue #55973, [2.8] Crash when 'apply pose as rest pose' when bone scale is 0,0,0
|
@ -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 Object *ob, struct bArmature *arm);
|
||||
void BKE_pose_rebuild(struct Main *bmain, struct Object *ob, struct bArmature *arm);
|
||||
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);
|
||||
|
|
|
@ -75,7 +75,7 @@ bool BKE_object_support_modifier_type_check(const struct Object *ob, int modifie
|
|||
void BKE_object_link_modifiers(struct Scene *scene, struct Object *ob_dst, const struct Object *ob_src);
|
||||
void BKE_object_free_modifiers(struct Object *ob, const int flag);
|
||||
|
||||
void BKE_object_make_proxy(struct Object *ob, struct Object *target, struct Object *gob);
|
||||
void BKE_object_make_proxy(struct Main *bmain, struct Object *ob, struct Object *target, struct Object *gob);
|
||||
void BKE_object_copy_proxy_drivers(struct Object *ob, struct Object *target);
|
||||
|
||||
bool BKE_object_exists_check(struct Main *bmain, const struct Object *obtest);
|
||||
|
|
|
@ -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 */
|
||||
|
||||
ob->pose->flag &= ~POSE_RECALC;
|
||||
ob->pose->flag |= POSE_WAS_REBUILT;
|
||||
pose->flag &= ~POSE_RECALC;
|
||||
pose->flag |= POSE_WAS_REBUILT;
|
||||
|
||||
BKE_pose_channels_hash_make(ob->pose);
|
||||
BKE_pose_channels_hash_make(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... */
|
||||
|
||||
|
|
|
@ -2464,7 +2464,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(ob, ob->data);
|
||||
BKE_pose_rebuild(bmain, ob, ob->data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1150,7 +1150,7 @@ void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
|
|||
*
|
||||
* \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
|
||||
*/
|
||||
void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_src, const int flag)
|
||||
void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, const int flag)
|
||||
{
|
||||
ModifierData *md;
|
||||
|
||||
|
@ -1180,7 +1180,7 @@ void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_
|
|||
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(ob_dst, ob_dst->data);
|
||||
BKE_pose_rebuild(bmain, ob_dst, ob_dst->data);
|
||||
}
|
||||
defgroup_copy_list(&ob_dst->defbase, &ob_src->defbase);
|
||||
BKE_object_facemap_copy_list(&ob_dst->fmaps, &ob_src->fmaps);
|
||||
|
@ -1359,7 +1359,7 @@ void BKE_object_copy_proxy_drivers(Object *ob, Object *target)
|
|||
/* local_object->proxy == pointer to library object, saved in files and read */
|
||||
/* local_object->proxy_group == pointer to collection dupli-object, saved in files and read */
|
||||
|
||||
void BKE_object_make_proxy(Object *ob, Object *target, Object *cob)
|
||||
void BKE_object_make_proxy(Main *bmain, Object *ob, Object *target, Object *cob)
|
||||
{
|
||||
/* paranoia checks */
|
||||
if (ID_IS_LINKED(ob) || !ID_IS_LINKED(target)) {
|
||||
|
@ -1434,7 +1434,7 @@ void BKE_object_make_proxy(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(ob, ob->data); /* set all internal links */
|
||||
BKE_pose_rebuild(bmain, ob, ob->data); /* set all internal links */
|
||||
|
||||
armature_set_id_extern(ob);
|
||||
}
|
||||
|
@ -2698,8 +2698,10 @@ void BKE_object_handle_update_ex(Depsgraph *depsgraph,
|
|||
* with poses we do it ahead of BKE_object_where_is_calc to ensure animation
|
||||
* is evaluated on the rebuilt pose, otherwise we get incorrect poses
|
||||
* on file load */
|
||||
if (ob->pose == NULL || (ob->pose->flag & POSE_RECALC))
|
||||
BKE_pose_rebuild(ob, ob->data);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* XXX new animsys warning: depsgraph tag OB_RECALC_DATA should not skip drivers,
|
||||
|
|
|
@ -1288,7 +1288,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(ob, ob->data);
|
||||
BKE_pose_rebuild(bmain, ob, ob->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -161,7 +161,8 @@ void DepsgraphNodeBuilder::build_rig(Object *object)
|
|||
build_armature(armature);
|
||||
/* Rebuild pose if not up to date. */
|
||||
if (object->pose == NULL || (object->pose->flag & POSE_RECALC)) {
|
||||
BKE_pose_rebuild(object, armature);
|
||||
/* By definition, no need to tag depsgraph as dirty from here, so we can pass NULL bmain. */
|
||||
BKE_pose_rebuild(NULL, object, armature);
|
||||
/* XXX: Without this animation gets lost in certain circumstances
|
||||
* after loading file. Need to investigate further since it does
|
||||
* not happen with simple scenes..
|
||||
|
|
|
@ -1623,7 +1623,7 @@ static void draw_armature_pose(Object *ob, const float const_color[4])
|
|||
|
||||
/* We can't safely draw non-updated pose, might contain NULL bone pointers... */
|
||||
if (ob->pose->flag & POSE_RECALC) {
|
||||
BKE_pose_rebuild(ob, arm);
|
||||
BKE_pose_rebuild(NULL, ob, arm);
|
||||
}
|
||||
|
||||
// if (!(base->flag & OB_FROMDUPLI)) // TODO
|
||||
|
|
|
@ -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(obt, arm);
|
||||
BKE_pose_rebuild(bmain, obt, arm);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2222,7 +2222,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(obn, obn->data);
|
||||
BKE_pose_rebuild(bmain, obn, obn->data);
|
||||
didit = 1;
|
||||
}
|
||||
id_us_min(id);
|
||||
|
|
|
@ -360,7 +360,7 @@ static int make_proxy_exec(bContext *C, wmOperator *op)
|
|||
newob = BKE_object_add_from(bmain, scene, view_layer, OB_EMPTY, name, gob ? gob : ob);
|
||||
|
||||
/* set layers OK */
|
||||
BKE_object_make_proxy(newob, ob, gob);
|
||||
BKE_object_make_proxy(bmain, newob, ob, gob);
|
||||
|
||||
/* Set back pointer immediately so dependency graph knows that this is
|
||||
* is a proxy and will act accordingly. Otherwise correctness of graph
|
||||
|
@ -1809,7 +1809,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(ob, ob->data);
|
||||
BKE_pose_rebuild(bmain, ob, ob->data);
|
||||
break;
|
||||
case OB_SPEAKER:
|
||||
ob->data = ID_NEW_SET(ob->data, BKE_speaker_copy(bmain, ob->data));
|
||||
|
|
|
@ -356,10 +356,12 @@ static void rna_Object_data_set(PointerRNA *ptr, PointerRNA value)
|
|||
ob->data = id;
|
||||
test_object_materials(G_MAIN, ob, id);
|
||||
|
||||
if (GS(id->name) == ID_CU)
|
||||
if (GS(id->name) == ID_CU) {
|
||||
BKE_curve_type_test(ob);
|
||||
else if (ob->type == OB_ARMATURE)
|
||||
BKE_pose_rebuild(ob, ob->data);
|
||||
}
|
||||
else if (ob->type == OB_ARMATURE) {
|
||||
BKE_pose_rebuild(G_MAIN, ob, ob->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue