diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2016-07-21 17:15:00 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2016-07-21 17:54:36 +0300 |
commit | af2deb5438e8f402901d31edd94a8457f006c4f1 (patch) | |
tree | 114e957e95fd1ac3b83cc5ecb373cb7f262f82a1 /source | |
parent | b1566742516a66d2b68ebb4bacb6802582c09489 (diff) |
Fix (unreported) crash in some case when remapping armature data.
Those bone pointers in object's pose bite again - turns out they can be accessed
before pose actually gets rebuilt in some cases (e.g. from undo writefile), so
we need to clear the pointers immediately.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_armature.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 16 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/library_remap.c | 3 |
3 files changed, 16 insertions, 4 deletions
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index 226cc6aa83d..c2323100205 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -95,6 +95,7 @@ float distfactor_to_bone(const float vec[3], const float b1[3], const float b2[3 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_rebuild(struct Object *ob, struct bArmature *arm); void BKE_pose_where_is(struct Scene *scene, struct Object *ob); void BKE_pose_where_is_bone(struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime, bool do_extra); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index b618eb5561e..790272c4411 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -1906,6 +1906,17 @@ static int rebuild_pose_bone(bPose *pose, Bone *bone, bPoseChannel *parchan, int return counter; } +/** + * Clear pointers of object's pose (needed in remap case, since we cannot always wait for a complete pose rebuild). + */ +void BKE_pose_clear_pointers(bPose *pose) +{ + for (bPoseChannel *pchan = pose->chanbase.first; pchan; pchan = pchan->next) { + pchan->bone = NULL; + pchan->child = 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) @@ -1926,10 +1937,7 @@ void BKE_pose_rebuild(Object *ob, bArmature *arm) pose = ob->pose; /* clear */ - for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { - pchan->bone = NULL; - pchan->child = NULL; - } + BKE_pose_clear_pointers(pose); /* first step, check if all channels are there */ for (bone = arm->bonebase.first; bone; bone = bone->next) { diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c index f3e6ec1ec51..74b3b1b6c18 100644 --- a/source/blender/blenkernel/intern/library_remap.c +++ b/source/blender/blenkernel/intern/library_remap.c @@ -296,6 +296,9 @@ static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data) if (ob->pose && (!old_id || ob->data == old_id)) { BLI_assert(ob->type == OB_ARMATURE); ob->pose->flag |= POSE_RECALC; + /* We need to clear pose bone pointers immediately, things like undo writefile may be called + * before pose is actually recomputed, can lead to segfault... */ + BKE_pose_clear_pointers(ob->pose); } } break; |