Blender V5.0
animation.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2022 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstring>
10
11#include "DNA_anim_types.h"
12#include "DNA_scene_types.h"
13#include "DNA_sequence_types.h"
14
15#include "BKE_fcurve.hh"
16
17#include "BLI_listbase.h"
18
19#include "DEG_depsgraph.hh"
20
21#include "SEQ_animation.hh"
22
23namespace blender::seq {
24
26{
27 return scene->adt != nullptr && scene->adt->action != nullptr &&
28 scene->adt->action->wrap().has_keyframes(scene->adt->slot_handle);
29}
30
32{
33 return scene->adt != nullptr && !BLI_listbase_is_empty(&scene->adt->drivers);
34}
35
36bool fcurve_matches(const Strip &strip, const FCurve &fcurve)
37{
39 fcurve, "sequence_editor.strips_all[", strip.name + 2);
40}
41
42void offset_animdata(const Scene *scene, Strip *strip, float ofs)
43{
44 if (!animation_keyframes_exist(scene) || ofs == 0.0f) {
45 return;
46 }
47
49 scene->adt->action, scene->adt->slot_handle, [&](const FCurve &fcurve) {
50 return fcurve_matches(*strip, fcurve);
51 });
52
53 for (FCurve *fcu : fcurves) {
54 uint i;
55 if (fcu->bezt) {
56 for (i = 0; i < fcu->totvert; i++) {
57 BezTriple *bezt = &fcu->bezt[i];
58 bezt->vec[0][0] += ofs;
59 bezt->vec[1][0] += ofs;
60 bezt->vec[2][0] += ofs;
61 }
62 }
63 if (fcu->fpt) {
64 for (i = 0; i < fcu->totvert; i++) {
65 FPoint *fpt = &fcu->fpt[i];
66 fpt->vec[0] += ofs;
67 }
68 }
69 }
70
72}
73
74void free_animdata(Scene *scene, Strip *strip)
75{
76 if (!animation_keyframes_exist(scene)) {
77 return;
78 }
79
81 scene->adt->action, scene->adt->slot_handle, [&](const FCurve &fcurve) {
82 return fcurve_matches(*strip, fcurve);
83 });
84
85 animrig::Action &action = scene->adt->action->wrap();
86 for (FCurve *fcu : fcurves) {
87 action_fcurve_remove(action, *fcu);
88 }
89}
90
92{
93 if (animation_keyframes_exist(scene)) {
94 animrig::Action &action = scene->adt->action->wrap();
95
96 assert_baklava_phase_1_invariants(action);
97
98 if (action.is_action_legacy()) {
99 BLI_movelisttolist(&backup->curves, &scene->adt->action->curves);
100 }
102 action, scene->adt->slot_handle))
103 {
104 animrig::channelbag_fcurves_move(backup->channelbag, *channelbag);
105 }
106 }
107
108 if (animation_drivers_exist(scene)) {
109 BLI_movelisttolist(&backup->drivers, &scene->adt->drivers);
110 }
111}
112
114{
115 if (!BLI_listbase_is_empty(&backup->curves) || !backup->channelbag.fcurves().is_empty()) {
116 BLI_assert(scene->adt != nullptr && scene->adt->action != nullptr);
117
118 animrig::Action &action = scene->adt->action->wrap();
119
120 assert_baklava_phase_1_invariants(action);
121
122 if (action.is_action_legacy()) {
123 BLI_movelisttolist(&scene->adt->action->curves, &backup->curves);
124 }
125 else {
127 action, scene->adt->slot_handle);
128 /* The channel bag should exist if we got here, because otherwise the
129 * backup channel bag would have been empty. */
130 BLI_assert(channelbag != nullptr);
131
132 animrig::channelbag_fcurves_move(*channelbag, backup->channelbag);
133 }
134 }
135
136 if (!BLI_listbase_is_empty(&backup->drivers)) {
137 BLI_assert(scene->adt != nullptr);
138 BLI_movelisttolist(&scene->adt->drivers, &backup->drivers);
139 }
140}
141
146 animrig::Action &dst,
147 const animrig::slot_handle_t dst_slot_handle,
148 AnimationBackup *src)
149{
150 if (strip->type == STRIP_TYPE_META) {
151 LISTBASE_FOREACH (Strip *, meta_child, &strip->seqbase) {
152 strip_animation_duplicate(meta_child, dst, dst_slot_handle, src);
153 }
154 }
155
156 Vector<FCurve *> fcurves = {};
158 "SeqAnimationBackup has fcurves for both legacy and layered actions, which "
159 "should never happen.");
160 if (BLI_listbase_is_empty(&src->curves)) {
162 src->channelbag.fcurves(),
163 [&](const FCurve &fcurve) { return fcurve_matches(*strip, fcurve); });
164 }
165 else {
167 src->curves, [&](const FCurve &fcurve) { return fcurve_matches(*strip, fcurve); });
168 }
169
170 for (const FCurve *fcu : fcurves) {
171 FCurve *fcu_copy = BKE_fcurve_copy(fcu);
172
173 /* Handling groups properly requires more work, so we ignore them for now.
174 *
175 * Note that when legacy actions are deprecated, then we can handle channel
176 * groups way more easily because we know they're stored in the
177 * already-duplicated channelbag in `src`, and we therefore don't have to
178 * worry that they might have already been freed. */
179 fcu_copy->grp = nullptr;
180
181 animrig::action_fcurve_attach(dst, dst_slot_handle, *fcu_copy, std::nullopt);
182 }
183}
184
189{
190 if (strip->type == STRIP_TYPE_META) {
191 LISTBASE_FOREACH (Strip *, meta_child, &strip->seqbase) {
192 strip_drivers_duplicate(meta_child, dst, src);
193 }
194 }
195
197 src->drivers, [&](const FCurve &fcurve) { return fcurve_matches(*strip, fcurve); });
198
199 for (const FCurve *fcu : fcurves) {
200 FCurve *fcu_cpy = BKE_fcurve_copy(fcu);
201 BLI_addtail(&dst->drivers, fcu_cpy);
202 }
203}
204
206{
207 BLI_assert(scene != nullptr);
208
209 if (!BLI_listbase_is_empty(&backup->curves) || !backup->channelbag.fcurves().is_empty()) {
210 BLI_assert(scene->adt != nullptr);
211 BLI_assert(scene->adt->action != nullptr);
212 strip_animation_duplicate(strip, scene->adt->action->wrap(), scene->adt->slot_handle, backup);
213 }
214
215 if (!BLI_listbase_is_empty(&backup->drivers)) {
216 BLI_assert(scene->adt != nullptr);
217 strip_drivers_duplicate(strip, scene->adt, backup);
218 }
219}
220
221} // namespace blender::seq
FCurve * BKE_fcurve_copy(const FCurve *fcu)
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
void void void BLI_movelisttolist(ListBase *dst, ListBase *src) ATTR_NONNULL(1
#define LISTBASE_FOREACH(type, var, list)
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
unsigned int uint
void DEG_id_tag_update(ID *id, unsigned int flags)
@ ID_RECALC_ANIMATION
Definition DNA_ID.h:1077
@ STRIP_TYPE_META
blender::Span< const FCurve * > fcurves() const
void action_fcurve_attach(Action &action, slot_handle_t action_slot, FCurve &fcurve_to_attach, std::optional< StringRefNull > group_name)
bool fcurve_matches_collection_path(const FCurve &fcurve, StringRefNull collection_rna_path, StringRefNull data_name)
void channelbag_fcurves_move(Channelbag &channelbag_dst, Channelbag &channelbag_src)
Vector< FCurve * > fcurves_in_listbase_filtered(ListBase fcurves, FunctionRef< bool(const FCurve &fcurve)> predicate)
Vector< FCurve * > fcurves_in_action_slot_filtered(bAction *act, slot_handle_t slot_handle, FunctionRef< bool(const FCurve &fcurve)> predicate)
const animrig::Channelbag * channelbag_for_action_slot(const Action &action, slot_handle_t slot_handle)
Vector< FCurve * > fcurves_in_span_filtered(Span< FCurve * > fcurves, FunctionRef< bool(const FCurve &fcurve)> predicate)
decltype(::ActionSlot::handle) slot_handle_t
static void strip_drivers_duplicate(Strip *strip, AnimData *dst, AnimationBackup *src)
Definition animation.cc:188
static void strip_animation_duplicate(Strip *strip, animrig::Action &dst, const animrig::slot_handle_t dst_slot_handle, AnimationBackup *src)
Definition animation.cc:145
bool animation_keyframes_exist(const Scene *scene)
Definition animation.cc:25
void animation_duplicate_backup_to_scene(Scene *scene, Strip *strip, AnimationBackup *backup)
Definition animation.cc:205
void offset_animdata(const Scene *scene, Strip *strip, float ofs)
Definition animation.cc:42
bool animation_drivers_exist(Scene *scene)
Definition animation.cc:31
void free_animdata(Scene *scene, Strip *strip)
Definition animation.cc:74
void animation_backup_original(Scene *scene, AnimationBackup *backup)
Definition animation.cc:91
void animation_restore_original(Scene *scene, AnimationBackup *backup)
Definition animation.cc:113
bool fcurve_matches(const Strip &strip, const FCurve &fcurve)
Definition animation.cc:36
bAction * action
int32_t slot_handle
ListBase drivers
float vec[3][3]
bActionGroup * grp
float vec[2]
struct AnimData * adt
ListBase seqbase
char name[64]
ListBase curves
blender::animrig::Channelbag channelbag
i
Definition text_draw.cc:230