Blender V4.5
sequencer_clipboard.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 * SPDX-FileCopyrightText: 2003-2009 Blender Authors
3 * SPDX-FileCopyrightText: 2005-2006 Peter Schlaile <peter [at] schlaile [dot] de>
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later */
6
10
11#include <algorithm>
12#include <cstring>
13
14#include "BLO_readfile.hh"
15#include "BLO_writefile.hh"
16#include "MEM_guardedalloc.h"
17
18#include "ED_outliner.hh"
19#include "ED_sequencer.hh"
20
21#include "DNA_anim_types.h"
22#include "DNA_scene_types.h"
23#include "DNA_sequence_types.h"
24#include "DNA_space_types.h"
26
27#include "BLI_listbase.h"
28#include "BLI_path_utils.hh"
29
30#include "BKE_anim_data.hh"
31#include "BKE_appdir.hh"
33#include "BKE_blendfile.hh"
34#include "BKE_context.hh"
35#include "BKE_fcurve.hh"
36#include "BKE_lib_id.hh"
37#include "BKE_lib_query.hh"
38#include "BKE_lib_remap.hh"
39#include "BKE_main.hh"
40#include "BKE_report.hh"
41#include "BKE_scene.hh"
42
43#include "SEQ_animation.hh"
44#include "SEQ_iterator.hh"
45#include "SEQ_select.hh"
46#include "SEQ_sequencer.hh"
47#include "SEQ_time.hh"
48#include "SEQ_transform.hh"
49#include "SEQ_utils.hh"
50
51#include "DEG_depsgraph.hh"
53
54#include "ANIM_action.hh"
55#include "ANIM_action_legacy.hh"
56#include "ANIM_animdata.hh"
57
58#include "WM_api.hh"
59#include "WM_types.hh"
60
61#ifdef WITH_AUDASPACE
62# include <AUD_Special.h>
63#endif
64
65/* Own include. */
66#include "sequencer_intern.hh"
67
68namespace blender::ed::vse {
69
70using namespace bke::blendfile;
71
72/* -------------------------------------------------------------------- */
73/* Copy Operator Helper functions
74 */
75
77 Strip *strip_dst,
78 ListBase *clipboard_dst,
79 ListBase *fcurve_base_src)
80{
81 /* Add curves for strips inside meta strip. */
82 if (strip_dst->type == STRIP_TYPE_META) {
83 LISTBASE_FOREACH (Strip *, meta_child, &strip_dst->seqbase) {
84 sequencer_copy_animation_listbase(scene_src, meta_child, clipboard_dst, fcurve_base_src);
85 }
86 }
87
89 *fcurve_base_src,
90 [&](const FCurve &fcurve) { return seq::fcurve_matches(*strip_dst, fcurve); });
91
92 for (FCurve *fcu_src : fcurves_src) {
93 BLI_addtail(clipboard_dst, BKE_fcurve_copy(fcu_src));
94 }
95}
96
97/* This is effectively just a copy of `sequencer_copy_animation_listbase()`
98 * above, except that it copies from an action's animation to a vector rather
99 * than between two listbases. */
101 Strip *strip_dst,
102 Vector<FCurve *> &clipboard_dst,
103 bAction &fcurves_src_action,
104 animrig::slot_handle_t fcurves_src_slot_handle)
105{
106 /* Add curves for strips inside meta strip. */
107 if (strip_dst->type == STRIP_TYPE_META) {
108 LISTBASE_FOREACH (Strip *, meta_child, &strip_dst->seqbase) {
110 scene_src, meta_child, clipboard_dst, fcurves_src_action, fcurves_src_slot_handle);
111 }
112 }
113
115 &fcurves_src_action, fcurves_src_slot_handle, [&](const FCurve &fcurve) {
116 return seq::fcurve_matches(*strip_dst, fcurve);
117 });
118
119 for (FCurve *fcu_src : fcurves_src) {
120 FCurve *fcu_copy = BKE_fcurve_copy(fcu_src);
121
122 /* Handling groups properly requires more work, so for now just ignore them. */
123 fcu_copy->grp = nullptr;
124
125 clipboard_dst.append(fcu_copy);
126 }
127}
128
129static void sequencer_copy_animation(Scene *scene_src,
130 Vector<FCurve *> &fcurves_dst,
131 ListBase *drivers_dst,
132 Strip *strip_dst)
133{
134 if (seq::animation_keyframes_exist(scene_src)) {
136 scene_src, strip_dst, fcurves_dst, *scene_src->adt->action, scene_src->adt->slot_handle);
137 }
138 if (seq::animation_drivers_exist(scene_src)) {
139 sequencer_copy_animation_listbase(scene_src, strip_dst, drivers_dst, &scene_src->adt->drivers);
140 }
141}
142
143static void sequencer_copybuffer_filepath_get(char filepath[FILE_MAX], size_t filepath_maxncpy)
144{
145 BLI_path_join(filepath, filepath_maxncpy, BKE_tempdir_base(), "copybuffer_vse.blend");
146}
147
149 Scene *scene_src,
150 const char *filepath,
152
153{
154 /* NOTE: Setting the same current file path as G_MAIN is necessary for now to get correct
155 * external filepaths when writing the partial write context on disk. otherwise, filepaths from
156 * the scene's sequencer strips (e.g. image ones) would also need to be remapped in this code. */
157 PartialWriteContext copy_buffer{bmain_src->filepath};
158 const char *scene_name = "copybuffer_vse_scene";
159
160 /* Add a dummy empty scene to the temporary Main copy buffer. */
161 Scene *scene_dst = reinterpret_cast<Scene *>(
162 copy_buffer.id_create(ID_SCE,
163 scene_name,
164 nullptr,
165 {(PartialWriteContext::IDAddOperations::SET_FAKE_USER |
166 PartialWriteContext::IDAddOperations::SET_CLIPBOARD_MARK)}));
167
168 /* Create an empty sequence editor data to store all copied strips. */
169 scene_dst->ed = MEM_callocN<Editing>(__func__);
170 scene_dst->ed->seqbasep = &scene_dst->ed->seqbase;
172 scene_src, scene_dst, &scene_dst->ed->seqbase, scene_src->ed->seqbasep, 0, 0);
173
174 BLI_duplicatelist(&scene_dst->ed->channels, &scene_src->ed->channels);
175 scene_dst->ed->displayed_channels = &scene_dst->ed->channels;
176
177 /* Save current frame and active strip. */
178 scene_dst->r.cfra = scene_src->r.cfra;
179 Strip *active_seq_src = seq::select_active_get(scene_src);
180 if (active_seq_src) {
181 Strip *strip_dst = static_cast<Strip *>(
182 BLI_findstring(&scene_dst->ed->seqbase, active_seq_src->name, offsetof(Strip, name)));
183 if (strip_dst) {
184 seq::select_active_set(scene_dst, strip_dst);
185 }
186 }
187
188 Vector<FCurve *> fcurves_dst = {};
189 ListBase drivers_dst = {nullptr, nullptr};
190 LISTBASE_FOREACH (Strip *, strip_dst, &scene_dst->ed->seqbase) {
191 /* Copy any fcurves/drivers from `scene_src` that are relevant to `strip_dst`. */
192 sequencer_copy_animation(scene_src, fcurves_dst, &drivers_dst, strip_dst);
193 }
194
195 BLI_assert(scene_dst->adt == nullptr);
196
197 /* Copy over the fcurves. */
198 if (!fcurves_dst.is_empty()) {
199 scene_dst->adt = BKE_animdata_ensure_id(&scene_dst->id);
200 animrig::Action &action_dst =
201 reinterpret_cast<bAction *>(
202 copy_buffer.id_create(
203 ID_AC, scene_name, nullptr, {PartialWriteContext::IDAddOperations::SET_FAKE_USER}))
204 ->wrap();
205
206 /* Assign the `dst_action` as either legacy or layered, depending on what
207 * the source action we're copying from is. */
209 const bool success = animrig::assign_action(&action_dst, scene_dst->id);
210 if (!success) {
211 return false;
212 }
213 }
214 else {
215 /* If we're copying from a layered action, also ensure a connected slot. */
217 scene_dst->id);
218 if (slot == nullptr) {
219 return false;
220 }
221 }
222
223 for (FCurve *fcurve : fcurves_dst) {
225 scene_dst->adt->slot_handle,
226 *fcurve,
227 fcurve->grp ? std::optional(fcurve->grp->name) : std::nullopt);
228 }
229 }
230
231 /* Copy over the drivers. */
232 if (!BLI_listbase_is_empty(&drivers_dst)) {
233 scene_dst->adt = BKE_animdata_ensure_id(&scene_dst->id);
234 BLI_movelisttolist(&scene_dst->adt->drivers, &drivers_dst);
235 }
236
237 /* Only add to the paste buffer some dependency ID types. For example, scenes are ignored/cleared
238 * (how to copy and paste scene strips is not clear currently).
239 */
240 /* NOTE: since a special Scene root ID needs to be forged for the VSE copy/paste (instead of
241 * directly using the current scene and adding it to the paste buffer), the first level of
242 * dependencies (IDs directly used by the scene) need to be processed manually here.
243 *
244 * All other indirect dependencies will then be handled automatically by the partial write
245 * context code.
246 */
247#define VSE_COPYBUFFER_IDTYPES ID_SO, ID_MC, ID_IM, ID_TXT, ID_VF, ID_AC
248 auto add_scene_ids_dependencies_cb = [&copy_buffer,
249 scene_dst](LibraryIDLinkCallbackData *cb_data) -> int {
250 ID *id_src = *cb_data->id_pointer;
251
252 /* Embedded or null IDs usages can be ignored here. */
253 if (cb_data->cb_flag & (IDWALK_CB_EMBEDDED | IDWALK_CB_EMBEDDED_NOT_OWNING)) {
254 return IDWALK_RET_NOP;
255 }
256 if (!id_src) {
257 return IDWALK_RET_NOP;
258 }
259
260 /* The Action ID of the destination scene has already been added (created actually) in the copy
261 * buffer. This is necessary to ensure that only the relevant sequencer-related animation data
262 * is copied into the destination paste buffer, and not the whole scene's animation. See the
263 * code around the call to #sequencer_copy_animation above.
264 *
265 * So trying to add it again here would lead to serious issues. */
266 if (scene_dst->adt && scene_dst->adt->action == reinterpret_cast<bAction *>(id_src)) {
267 BLI_assert(GS(id_src->name) == ID_AC);
268 return IDWALK_RET_NOP;
269 }
270
271 ID *id_dst = nullptr;
272 const ID_Type id_type = GS((id_src)->name);
273 /* Only add (and follow) IDs which usage is marked as 'never null', or are from following
274 * types: #bSound, #MovieClip, #Image, #Text, #VFont, #bAction. */
275 if (ELEM(id_type, VSE_COPYBUFFER_IDTYPES) || (cb_data->cb_flag & IDWALK_CB_NEVER_NULL)) {
276 /* The partial write context handle dependencies of ID added to it. This callback will tell
277 * it whether a given dependency ID should be skipped/cleared, or also added in the context.
278 */
279 auto partial_write_dependencies_filter_cb = [](LibraryIDLinkCallbackData *cb_deps_data,
282 ID *id_deps_src = *cb_deps_data->id_pointer;
283 const ID_Type id_type = GS((id_deps_src)->name);
284 if (ELEM(id_type, VSE_COPYBUFFER_IDTYPES) ||
285 (cb_deps_data->cb_flag & IDWALK_CB_NEVER_NULL))
286 {
287 return PartialWriteContext::IDAddOperations::ADD_DEPENDENCIES;
288 }
289 return PartialWriteContext::IDAddOperations::CLEAR_DEPENDENCIES;
290 };
291 id_dst = copy_buffer.id_add(id_src,
292 {PartialWriteContext::IDAddOperations::NOP},
293 partial_write_dependencies_filter_cb);
294 }
295 *cb_data->id_pointer = id_dst;
296 return IDWALK_RET_NOP;
297 };
299 nullptr, &scene_dst->id, add_scene_ids_dependencies_cb, nullptr, IDWALK_NOP);
300#undef VSE_COPYBUFFER_IDTYPES
301
302 BLI_assert(copy_buffer.is_valid());
303
304 const bool retval = copy_buffer.write(filepath, reports);
305
306 return retval;
307}
308
310{
311 Main *bmain = CTX_data_main(C);
312 Scene *scene = CTX_data_scene(C);
313 Editing *ed = seq::editing_get(scene);
314
316
317 if (selected.is_empty()) {
318 return OPERATOR_CANCELLED;
319 }
320
321 blender::VectorSet<Strip *> effect_chain;
322 effect_chain.add_multiple(selected);
323 seq::iterator_set_expand(scene, ed->seqbasep, effect_chain, seq::query_strip_effect_chain);
324
326 for (Strip *strip : effect_chain) {
327 if (!(strip->flag & SELECT)) {
328 strip->flag |= SELECT;
329 expanded.add(strip);
330 }
331 }
332
333 char filepath[FILE_MAX];
334 sequencer_copybuffer_filepath_get(filepath, sizeof(filepath));
335 bool success = sequencer_write_copy_paste_file(bmain, scene, filepath, *op->reports);
336 if (!success) {
337 BKE_report(op->reports, RPT_ERROR, "Could not create the copy paste file!");
338 for (Strip *strip : expanded) {
339 strip->flag &= ~SELECT;
340 }
341 return OPERATOR_CANCELLED;
342 }
343
344 /* We are all done! */
345 if (effect_chain.size() > selected.size()) {
347 RPT_INFO,
348 "Copied the selected Video Sequencer strips and associated effect chain to "
349 "internal clipboard");
350 }
351 else {
353 op->reports, RPT_INFO, "Copied the selected Video Sequencer strips to internal clipboard");
354 }
357 return OPERATOR_FINISHED;
358}
359
360/* -------------------------------------------------------------------- */
361/* Paste Operator Helper functions
362 */
363
364static bool sequencer_paste_animation(Main *bmain_dst, Scene *scene_dst, Scene *scene_src)
365{
366 if (!seq::animation_keyframes_exist(scene_src) && !seq::animation_drivers_exist(scene_src)) {
367 return false;
368 }
369
370 bAction *act_dst = animrig::id_action_ensure(bmain_dst, &scene_dst->id);
371
372 /* For layered actions ensure we have an attached slot. */
375 scene_dst->id);
376 BLI_assert(slot != nullptr);
377 if (slot == nullptr) {
378 return false;
379 }
380 }
381
383 animrig::action_fcurve_attach(act_dst->wrap(),
384 scene_dst->adt->slot_handle,
385 *BKE_fcurve_copy(fcu),
386 fcu->grp ? std::optional(fcu->grp->name) : std::nullopt);
387 }
388 LISTBASE_FOREACH (FCurve *, fcu, &scene_src->adt->drivers) {
389 BLI_addtail(&scene_dst->adt->drivers, BKE_fcurve_copy(fcu));
390 }
391
392 return true;
393}
394
396{
397 char filepath[FILE_MAX];
398 sequencer_copybuffer_filepath_get(filepath, sizeof(filepath));
400 BlendFileReadReport bf_reports{};
401 BlendFileData *bfd = BKE_blendfile_read(filepath, &params, &bf_reports);
402
403 if (bfd == nullptr) {
404 BKE_report(op->reports, RPT_INFO, "No data to paste");
405 return OPERATOR_CANCELLED;
406 }
407
408 Main *bmain_src = bfd->main;
409 bfd->main = nullptr;
411
412 Scene *scene_src = nullptr;
413 /* Find the scene we pasted that contains the strips. It should be tagged. */
414 LISTBASE_FOREACH (Scene *, scene_iter, &bmain_src->scenes) {
415 if (scene_iter->id.flag & ID_FLAG_CLIPBOARD_MARK) {
416 scene_src = scene_iter;
417 break;
418 }
419 }
420
421 if (!scene_src || !scene_src->ed) {
422 BKE_report(op->reports, RPT_ERROR, "No clipboard scene to paste Video Sequencer data from");
423 BKE_main_free(bmain_src);
424 return OPERATOR_CANCELLED;
425 }
426
427 const int num_strips_to_paste = BLI_listbase_count(&scene_src->ed->seqbase);
428 if (num_strips_to_paste == 0) {
429 BKE_report(op->reports, RPT_INFO, "No strips to paste");
430 BKE_main_free(bmain_src);
431 return OPERATOR_CANCELLED;
432 }
433
434 Scene *scene_dst = CTX_data_scene(C);
435 Editing *ed_dst = seq::editing_ensure(scene_dst); /* Creates "ed" if it's missing. */
436 int ofs;
437
438 deselect_all_strips(scene_dst);
439 if (RNA_boolean_get(op->ptr, "keep_offset")) {
440 ofs = scene_dst->r.cfra - scene_src->r.cfra;
441 }
442 else {
443 int min_seq_startdisp = INT_MAX;
444 LISTBASE_FOREACH (Strip *, strip, &scene_src->ed->seqbase) {
445 min_seq_startdisp = std::min(seq::time_left_handle_frame_get(scene_src, strip),
446 min_seq_startdisp);
447 }
448 /* Paste strips relative to the current-frame. */
449 ofs = scene_dst->r.cfra - min_seq_startdisp;
450 }
451
452 Strip *prev_active_seq = seq::select_active_get(scene_src);
453 std::string active_seq_name;
454 if (prev_active_seq) {
455 active_seq_name.assign(prev_active_seq->name);
456 }
457
458 /* Make sure we have all data IDs we need in bmain_dst. Remap the IDs if we already have them.
459 * This has to happen BEFORE we move the strip over to scene_dst. their ID mapping will not be
460 * correct otherwise. */
461 Main *bmain_dst = CTX_data_main(C);
462 MainMergeReport merge_reports = {};
463 /* NOTE: BKE_main_merge will free bmain_src! */
464 BKE_main_merge(bmain_dst, &bmain_src, merge_reports);
465
466 /* Paste animation.
467 * NOTE: Only fcurves and drivers are copied. NLA action strips are not copied.
468 * First backup original curves from scene and move curves from clipboard into scene. This way,
469 * when pasted strips are renamed, pasted fcurves are renamed with them. Finally restore original
470 * curves from backup.
471 */
472 seq::AnimationBackup animation_backup = {{nullptr}};
473 seq::animation_backup_original(scene_dst, &animation_backup);
474 bool has_animation = sequencer_paste_animation(bmain_dst, scene_dst, scene_src);
475
476 ListBase nseqbase = {nullptr, nullptr};
477 /* NOTE: seq::seqbase_duplicate_recursive() takes care of generating
478 * new UIDs for sequences in the new list. */
479 seq::seqbase_duplicate_recursive(scene_src, scene_dst, &nseqbase, &scene_src->ed->seqbase, 0, 0);
480
481 /* BKE_main_merge will copy the scene_src and its action into bmain_dst. Remove them as
482 * we merge the data from these manually.
483 */
484 if (has_animation && scene_src->adt->action != nullptr) {
485 BKE_id_delete(bmain_dst, scene_src->adt->action);
486 }
487 BKE_id_delete(bmain_dst, scene_src);
488
489 Strip *iseq_first = static_cast<Strip *>(nseqbase.first);
490 BLI_movelisttolist(ed_dst->seqbasep, &nseqbase);
491 /* Restore "first" pointer as BLI_movelisttolist sets it to nullptr */
492 nseqbase.first = iseq_first;
493
494 LISTBASE_FOREACH (Strip *, istrip, &nseqbase) {
495 if (istrip->name == active_seq_name) {
496 seq::select_active_set(scene_dst, istrip);
497 }
498 /* Make sure, that pasted strips have unique names. This has to be done after
499 * adding strips to seqbase, for lookup cache to work correctly. */
500 seq::ensure_unique_name(istrip, scene_dst);
501 }
502
503 LISTBASE_FOREACH (Strip *, istrip, &nseqbase) {
504 /* Translate after name has been changed, otherwise this will affect animdata of original
505 * strip. */
506 seq::transform_translate_strip(scene_dst, istrip, ofs);
507 /* Ensure, that pasted strips don't overlap. */
508 if (seq::transform_test_overlap(scene_dst, ed_dst->seqbasep, istrip)) {
509 seq::transform_seqbase_shuffle(ed_dst->seqbasep, istrip, scene_dst);
510 }
511 }
512
513 seq::animation_restore_original(scene_dst, &animation_backup);
514
516 if (scene_dst->adt && scene_dst->adt->action) {
518 }
519 DEG_relations_tag_update(bmain_dst);
523
524 BKE_reportf(op->reports, RPT_INFO, "%d strips pasted", num_strips_to_paste);
525
526 return OPERATOR_FINISHED;
527}
528} // namespace blender::ed::vse
Functions and classes to work with Actions.
Functions for backward compatibility with the legacy Action API.
Functions to work with AnimData.
AnimData * BKE_animdata_ensure_id(ID *id)
Definition anim_data.cc:96
const char * BKE_tempdir_base() ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
Definition appdir.cc:1249
BlendFileData * BKE_blendfile_read(const char *filepath, const BlendFileReadParams *params, BlendFileReadReport *reports)
Scene * CTX_data_scene(const bContext *C)
Main * CTX_data_main(const bContext *C)
FCurve * BKE_fcurve_copy(const FCurve *fcu)
void BKE_id_delete(Main *bmain, void *idv) ATTR_NONNULL()
@ IDWALK_CB_EMBEDDED_NOT_OWNING
@ IDWALK_CB_EMBEDDED
@ IDWALK_CB_NEVER_NULL
void BKE_library_foreach_ID_link(Main *bmain, ID *id, blender::FunctionRef< LibraryIDLinkCallback > callback, void *user_data, LibraryForeachIDFlag flag)
Definition lib_query.cc:431
@ IDWALK_RET_NOP
@ IDWALK_NOP
void BKE_main_merge(Main *bmain_dst, Main **r_bmain_src, MainMergeReport &reports)
Definition main.cc:321
void BKE_main_free(Main *bmain)
Definition main.cc:175
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
Definition report.cc:126
#define BLI_assert(a)
Definition BLI_assert.h:46
void void void BLI_movelisttolist(ListBase *dst, ListBase *src) ATTR_NONNULL(1
#define LISTBASE_FOREACH(type, var, list)
void * BLI_findstring(const ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:608
BLI_INLINE bool BLI_listbase_is_empty(const ListBase *lb)
void BLI_addtail(ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition listbase.cc:111
int BLI_listbase_count(const ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition listbase.cc:524
void void void void void void BLI_duplicatelist(ListBase *dst, const ListBase *src) ATTR_NONNULL(1
#define FILE_MAX
#define BLI_path_join(...)
#define ELEM(...)
external readfile function prototypes.
void BLO_blendfiledata_free(BlendFileData *bfd)
external writefile.cc function prototypes.
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
@ ID_FLAG_CLIPBOARD_MARK
Definition DNA_ID.h:712
@ ID_RECALC_SEQUENCER_STRIPS
Definition DNA_ID.h:1030
@ ID_RECALC_ANIMATION_NO_FLUSH
Definition DNA_ID.h:1084
ID_Type
@ ID_SCE
@ ID_AC
@ STRIP_TYPE_META
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
void ED_outliner_select_sync_from_sequence_tag(const bContext *C)
Read Guarded memory(de)allocation.
#define C
Definition RandGen.cpp:29
#define ND_SEQUENCER
Definition WM_types.hh:434
#define NC_SCENE
Definition WM_types.hh:375
ReportList * reports
Definition WM_types.hh:1025
#define ND_ANIMCHAN
Definition WM_types.hh:493
#define NA_SELECTED
Definition WM_types.hh:586
bool add(const Key &key)
void add_multiple(Span< Key > keys)
int64_t size() const
void append(const T &value)
bool is_empty() const
ID * id_add(const ID *id, IDAddOptions options, blender::FunctionRef< IDAddOperations(LibraryIDLinkCallbackData *cb_data, IDAddOptions options)> dependencies_filter_cb=nullptr)
bool write(const char *write_filepath, int write_flags, int remap_mode, ReportList &reports)
ID * id_create(short id_type, StringRefNull id_name, Library *library, IDAddOptions options)
#define SELECT
#define offsetof(t, d)
#define GS(a)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
void * MEM_callocN(size_t len, const char *str)
Definition mallocn.cc:118
Vector< FCurve * > fcurves_for_assigned_action(AnimData *adt)
bool action_treat_as_legacy(const bAction &action)
void action_fcurve_attach(Action &action, slot_handle_t action_slot, FCurve &fcurve_to_attach, std::optional< StringRefNull > group_name)
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)
Slot * assign_action_ensure_slot_for_keying(Action &action, ID &animated_id)
bAction * id_action_ensure(Main *bmain, ID *id)
Definition animdata.cc:195
decltype(::ActionSlot::handle) slot_handle_t
bool assign_action(bAction *action, ID &animated_id)
static void sequencer_copybuffer_filepath_get(char filepath[FILE_MAX], size_t filepath_maxncpy)
static void sequencer_copy_animation_to_vector(Scene *scene_src, Strip *strip_dst, Vector< FCurve * > &clipboard_dst, bAction &fcurves_src_action, animrig::slot_handle_t fcurves_src_slot_handle)
wmOperatorStatus sequencer_clipboard_copy_exec(bContext *C, wmOperator *op)
static bool sequencer_paste_animation(Main *bmain_dst, Scene *scene_dst, Scene *scene_src)
static void sequencer_copy_animation_listbase(Scene *scene_src, Strip *strip_dst, ListBase *clipboard_dst, ListBase *fcurve_base_src)
static bool sequencer_write_copy_paste_file(Main *bmain_src, Scene *scene_src, const char *filepath, ReportList &reports)
bool deselect_all_strips(const Scene *scene)
wmOperatorStatus sequencer_clipboard_paste_exec(bContext *C, wmOperator *op)
static void sequencer_copy_animation(Scene *scene_src, Vector< FCurve * > &fcurves_dst, ListBase *drivers_dst, Strip *strip_dst)
VectorSet< Strip * > query_selected_strips(ListBase *seqbase)
Definition iterator.cc:127
void transform_translate_strip(Scene *evil_scene, Strip *strip, int delta)
bool animation_keyframes_exist(const Scene *scene)
Definition animation.cc:25
bool transform_test_overlap(const Scene *scene, Strip *strip1, Strip *strip2)
Editing * editing_get(const Scene *scene)
Definition sequencer.cc:272
int time_left_handle_frame_get(const Scene *, const Strip *strip)
bool animation_drivers_exist(Scene *scene)
Definition animation.cc:31
void query_strip_effect_chain(const Scene *scene, Strip *reference_strip, ListBase *seqbase, VectorSet< Strip * > &r_strips)
Definition iterator.cc:231
Editing * editing_ensure(Scene *scene)
Definition sequencer.cc:277
Strip * select_active_get(const Scene *scene)
void iterator_set_expand(const Scene *scene, ListBase *seqbase, VectorSet< Strip * > &strips, void strip_query_func(const Scene *scene, Strip *strip_reference, ListBase *seqbase, VectorSet< Strip * > &strips))
Definition iterator.cc:82
void animation_backup_original(Scene *scene, AnimationBackup *backup)
Definition animation.cc:91
void select_active_set(Scene *scene, Strip *strip)
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
void ensure_unique_name(Strip *strip, Scene *scene)
void seqbase_duplicate_recursive(const Scene *scene_src, Scene *scene_dst, ListBase *nseqbase, const ListBase *seqbase, int dupe_flag, const int flag)
Definition sequencer.cc:692
bool transform_seqbase_shuffle(ListBase *seqbasep, Strip *test, Scene *evil_scene)
float wrap(float value, float max, float min)
Definition node_math.h:71
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
#define VSE_COPYBUFFER_IDTYPES
bAction * action
int32_t slot_handle
ListBase drivers
ListBase seqbase
ListBase * seqbasep
ListBase channels
ListBase * displayed_channels
bActionGroup * grp
Definition DNA_ID.h:404
char name[66]
Definition DNA_ID.h:415
LibraryForeachIDCallbackFlag cb_flag
void * first
ListBase scenes
Definition BKE_main.hh:245
char filepath[1024]
Definition BKE_main.hh:155
struct Editing * ed
struct RenderData r
struct AnimData * adt
ListBase seqbase
char name[64]
struct ReportList * reports
struct PointerRNA * ptr
void WM_event_add_notifier(const bContext *C, uint type, void *reference)