Fix T82758: Convert Proxy to Override: Local constraints aren't saved.
Ensure consistent order of pose bones. Now it should always match the one from bones in armature obdata (as exposed by e.g. RNA, i.e. children-first). Previously when some pose bones would need to be added or removed from a pose due to changes in the bone armature, or if bones in armature were re-ordered, the bones order in pose would not match anymore the one from armature, and could even become different between e.g. a proxy and its linked source. This was not really nice, but not a big issue before either. But with diffing process of override, consistent order of items between reference linked collection and local override one is crucial. Reviewed By: #animation_rigging, sybren Maniphest Tasks: T82758 Differential Revision: https://developer.blender.org/D9646
This commit is contained in:
parent
e4e7dfc1d8
commit
fbdf1af355
Notes:
blender-bot
2023-02-14 10:09:24 +01:00
Referenced by issue #82758, Convert Proxy to Override: Local constraints aren't saved Referenced by issue #82718, Tablet no longer working correctly in Sculpting - Blender 2.92 Referenced by issue #77314, Glare node bug when using NLM denoising
|
@ -2440,17 +2440,42 @@ static void pose_proxy_sync(Object *ob, Object *from, int layer_protected)
|
|||
}
|
||||
}
|
||||
|
||||
static int rebuild_pose_bone(bPose *pose, Bone *bone, bPoseChannel *parchan, int counter)
|
||||
/**
|
||||
* \param r_last_visited_bone_p the last bone handled by the last call to this function.
|
||||
*/
|
||||
static int rebuild_pose_bone(
|
||||
bPose *pose, Bone *bone, bPoseChannel *parchan, int counter, Bone **r_last_visited_bone_p)
|
||||
{
|
||||
bPoseChannel *pchan = BKE_pose_channel_verify(pose, bone->name); /* verify checks and/or adds */
|
||||
|
||||
pchan->bone = bone;
|
||||
pchan->parent = parchan;
|
||||
|
||||
/* We ensure the current pchan is immediately after the one we just generated/updated in the
|
||||
* previous call to `rebuild_pose_bone`.
|
||||
*
|
||||
* It may be either the parent, the previous sibling, or the last
|
||||
* (grand-(grand-(...)))-child (as processed by the recursive, depth-first nature of this
|
||||
* function) of the previous sibling.
|
||||
*
|
||||
* Note: In most cases there is nothing to do here, but pose list may get out of order when some
|
||||
* bones are added, removed or moved in the armature data. */
|
||||
bPoseChannel *pchan_prev = pchan->prev;
|
||||
const Bone *last_visited_bone = *r_last_visited_bone_p;
|
||||
if ((pchan_prev == NULL && last_visited_bone != NULL) ||
|
||||
(pchan_prev != NULL && pchan_prev->bone != last_visited_bone)) {
|
||||
pchan_prev = last_visited_bone != NULL ?
|
||||
BKE_pose_channel_find_name(pose, last_visited_bone->name) :
|
||||
NULL;
|
||||
BLI_remlink(&pose->chanbase, pchan);
|
||||
BLI_insertlinkafter(&pose->chanbase, pchan_prev, pchan);
|
||||
}
|
||||
|
||||
*r_last_visited_bone_p = pchan->bone;
|
||||
counter++;
|
||||
|
||||
for (bone = bone->childbase.first; bone; bone = bone->next) {
|
||||
counter = rebuild_pose_bone(pose, bone, pchan, counter);
|
||||
counter = rebuild_pose_bone(pose, bone, pchan, counter, r_last_visited_bone_p);
|
||||
/* for quick detecting of next bone in chain, only b-bone uses it now */
|
||||
if (bone->flag & BONE_CONNECTED) {
|
||||
pchan->child = BKE_pose_channel_find_name(pose, bone->name);
|
||||
|
@ -2520,8 +2545,9 @@ void BKE_pose_rebuild(Main *bmain, Object *ob, bArmature *arm, const bool do_id_
|
|||
BKE_pose_clear_pointers(pose);
|
||||
|
||||
/* first step, check if all channels are there */
|
||||
Bone *prev_bone = NULL;
|
||||
for (bone = arm->bonebase.first; bone; bone = bone->next) {
|
||||
counter = rebuild_pose_bone(pose, bone, NULL, counter);
|
||||
counter = rebuild_pose_bone(pose, bone, NULL, counter, &prev_bone);
|
||||
}
|
||||
|
||||
/* and a check for garbage */
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "DNA_workspace_types.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_colortools.h"
|
||||
#include "BKE_fcurve.h"
|
||||
|
@ -472,8 +473,15 @@ void do_versions_after_linking_290(Main *bmain, ReportList *UNUSED(reports))
|
|||
* \note Keep this message at the bottom of the function.
|
||||
*/
|
||||
{
|
||||
|
||||
/* Keep this block, even when empty. */
|
||||
|
||||
/* Systematically rebuild posebones to ensure consistent ordering matching the one of bones in
|
||||
* Armature obdata. */
|
||||
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
||||
if (ob->type == OB_ARMATURE) {
|
||||
BKE_pose_rebuild(bmain, ob, ob->data, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue