Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSybren A. Stüvel <sybren@blender.org>2020-11-30 18:12:55 +0300
committerSybren A. Stüvel <sybren@blender.org>2020-11-30 18:30:44 +0300
commit8c74c35ecb5b6416fcfc624e52c068ed90f48757 (patch)
tree85cd6244d4d1984b3df73880bf4b89f8be3aae7b /source/blender
parented9b70393c47ecd5736c7d9ca3216e5306ca7b73 (diff)
Fix T81628: Moving Python-made channels freezes Blender
Fix various problems in the Action Group rearranging code. All fixes are necessary to resolve the bug. - Before groups are rearranged, the channels are moved into their respective groups (so no longer referenced by `action->channels`). A temporary group is made for ungrouped channels. The code made assumptions about the channels being in the same order as the groups; that assumption has been removed. - Looping over channels in an Action Group should stop when reaching the last channel, and not until `NULL`. - After all the reshuffling is done, the `action->channels` linked list wasn't terminated properly. Now `first.prev` and `last.next` are set to `NULL` to avoid infinite loops.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c38
1 files changed, 31 insertions, 7 deletions
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 4c17d84b200..ba3796ad245 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -1213,15 +1213,29 @@ static void split_groups_action_temp(bAction *act, bActionGroup *tgrp)
/* Separate F-Curves into lists per group */
LISTBASE_FOREACH (bActionGroup *, agrp, &act->groups) {
- if (agrp->channels.first) {
- fcu = agrp->channels.last;
- act->curves.first = fcu->next;
+ FCurve *const group_fcurves_first = agrp->channels.first;
+ FCurve *const group_fcurves_last = agrp->channels.last;
+ if (group_fcurves_first == NULL) {
+ /* Empty group. */
+ continue;
+ }
- fcu = agrp->channels.first;
- fcu->prev = NULL;
+ if (group_fcurves_first == act->curves.first) {
+ /* First of the action curves, update the start of the action curves. */
+ BLI_assert(group_fcurves_first->prev == NULL);
+ act->curves.first = group_fcurves_last->next;
+ }
+ else {
+ group_fcurves_first->prev->next = group_fcurves_last->next;
+ }
- fcu = agrp->channels.last;
- fcu->next = NULL;
+ if (group_fcurves_last == act->curves.last) {
+ /* Last of the action curves, update the end of the action curves. */
+ BLI_assert(group_fcurves_last->next == NULL);
+ act->curves.last = group_fcurves_first->prev;
+ }
+ else {
+ group_fcurves_last->next->prev = group_fcurves_first->prev;
}
}
@@ -1277,12 +1291,22 @@ static void join_groups_action_temp(bAction *act)
if (agrp->flag & AGRP_TEMP) {
LISTBASE_FOREACH (FCurve *, fcu, &agrp->channels) {
fcu->grp = NULL;
+ if (fcu == agrp->channels.last) {
+ break;
+ }
}
BLI_remlink(&act->groups, agrp);
break;
}
}
+
+ /* BLI_movelisttolist() doesn't touch first->prev and last->next pointers in its "dst" list.
+ * Ensure that after the reshuffling the list is properly terminated. */
+ FCurve *act_fcurves_first = act->curves.first;
+ act_fcurves_first->prev = NULL;
+ FCurve *act_fcurves_last = act->curves.last;
+ act_fcurves_last->next = NULL;
}
/* Change the order of anim-channels within action