2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2009-01-12 19:02:08 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software Foundation,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2009-01-12 19:02:08 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* - Blender Foundation, 2003-2009
|
|
|
|
* - Peter Schlaile <peter [at] schlaile [dot] de> 2005/2006
|
|
|
|
*/
|
2008-12-15 05:21:44 +00:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
* \ingroup bke
|
2011-02-27 20:40:57 +00:00
|
|
|
*/
|
|
|
|
|
2008-12-15 05:21:44 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
2009-11-22 20:22:35 +00:00
|
|
|
#include "DNA_anim_types.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
#include "DNA_sequence_types.h"
|
2009-01-12 19:02:08 +00:00
|
|
|
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_listbase.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_string.h"
|
2015-04-06 10:40:12 -03:00
|
|
|
|
2010-07-07 16:17:18 +00:00
|
|
|
#include "BKE_animsys.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_fcurve.h"
|
|
|
|
#include "BKE_idprop.h"
|
|
|
|
#include "BKE_lib_id.h"
|
2020-11-16 05:02:30 +01:00
|
|
|
#include "BKE_sound.h"
|
2011-01-07 19:18:31 +00:00
|
|
|
|
2017-04-06 15:37:46 +02:00
|
|
|
#include "DEG_depsgraph.h"
|
2008-12-15 05:21:44 +00:00
|
|
|
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "IMB_colormanagement.h"
|
2008-12-15 05:21:44 +00:00
|
|
|
#include "IMB_imbuf.h"
|
2011-06-23 09:27:56 +00:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
#include "SEQ_sequencer.h"
|
2017-10-25 11:02:52 -02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
#include "image_cache.h"
|
|
|
|
#include "prefetch.h"
|
2020-10-26 00:47:06 +01:00
|
|
|
#include "sequencer.h"
|
2020-11-16 05:02:30 +01:00
|
|
|
#include "utils.h"
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2011-05-16 17:14:47 +00:00
|
|
|
static void seq_free_animdata(Scene *scene, Sequence *seq);
|
2020-05-10 08:26:24 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
/* -------------------------------------------------------------------- */
|
2020-11-16 16:48:41 +11:00
|
|
|
/** \name Allocate / Free Functions
|
2020-11-16 05:02:30 +01:00
|
|
|
* \{ */
|
2009-12-18 13:28:03 +00:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
static Strip *seq_strip_alloc(int type)
|
2009-12-18 13:28:03 +00:00
|
|
|
{
|
2020-11-16 05:02:30 +01:00
|
|
|
Strip *strip = MEM_callocN(sizeof(Strip), "strip");
|
2010-07-06 16:44:05 +00:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
if (ELEM(type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD) == 0) {
|
|
|
|
strip->transform = MEM_callocN(sizeof(struct StripTransform), "StripTransform");
|
|
|
|
strip->transform->scale_x = 1;
|
|
|
|
strip->transform->scale_y = 1;
|
|
|
|
strip->crop = MEM_callocN(sizeof(struct StripCrop), "StripCrop");
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2010-07-06 16:44:05 +00:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
strip->us = 1;
|
|
|
|
return strip;
|
2002-10-12 11:37:38 +00:00
|
|
|
}
|
|
|
|
|
2012-08-08 11:15:32 +00:00
|
|
|
static void seq_free_strip(Strip *strip)
|
2008-12-15 05:21:44 +00:00
|
|
|
{
|
|
|
|
strip->us--;
|
2019-04-22 09:39:35 +10:00
|
|
|
if (strip->us > 0) {
|
2012-08-08 11:15:36 +00:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-03-29 22:26:11 +00:00
|
|
|
if (strip->us < 0) {
|
2008-12-15 05:21:44 +00:00
|
|
|
printf("error: negative users in strip\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strip->stripdata) {
|
|
|
|
MEM_freeN(strip->stripdata);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strip->proxy) {
|
2009-06-08 20:08:19 +00:00
|
|
|
if (strip->proxy->anim) {
|
|
|
|
IMB_free_anim(strip->proxy->anim);
|
|
|
|
}
|
|
|
|
|
2008-12-15 05:21:44 +00:00
|
|
|
MEM_freeN(strip->proxy);
|
|
|
|
}
|
|
|
|
if (strip->crop) {
|
|
|
|
MEM_freeN(strip->crop);
|
|
|
|
}
|
|
|
|
if (strip->transform) {
|
|
|
|
MEM_freeN(strip->transform);
|
|
|
|
}
|
|
|
|
|
|
|
|
MEM_freeN(strip);
|
|
|
|
}
|
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
Sequence *BKE_sequence_alloc(ListBase *lb, int timeline_frame, int machine, int type)
|
|
|
|
{
|
|
|
|
Sequence *seq;
|
|
|
|
|
|
|
|
seq = MEM_callocN(sizeof(Sequence), "addseq");
|
|
|
|
BLI_addtail(lb, seq);
|
|
|
|
|
|
|
|
*((short *)seq->name) = ID_SEQ;
|
|
|
|
seq->name[2] = 0;
|
|
|
|
|
|
|
|
seq->flag = SELECT;
|
|
|
|
seq->start = timeline_frame;
|
|
|
|
seq->machine = machine;
|
|
|
|
seq->sat = 1.0;
|
|
|
|
seq->mul = 1.0;
|
|
|
|
seq->blend_opacity = 100.0;
|
|
|
|
seq->volume = 1.0f;
|
|
|
|
seq->pitch = 1.0f;
|
|
|
|
seq->scene_sound = NULL;
|
|
|
|
seq->type = type;
|
|
|
|
|
|
|
|
seq->strip = seq_strip_alloc(type);
|
|
|
|
seq->stereo3d_format = MEM_callocN(sizeof(Stereo3dFormat), "Sequence Stereo Format");
|
|
|
|
seq->cache_flag = SEQ_CACHE_STORE_RAW | SEQ_CACHE_STORE_PREPROCESSED | SEQ_CACHE_STORE_COMPOSITE;
|
|
|
|
|
|
|
|
BKE_sequence_session_uuid_generate(seq);
|
|
|
|
|
|
|
|
return seq;
|
|
|
|
}
|
|
|
|
|
2012-09-06 09:23:38 +00:00
|
|
|
/* only give option to skip cache locally (static func) */
|
2018-05-11 11:21:30 +02:00
|
|
|
static void BKE_sequence_free_ex(Scene *scene,
|
|
|
|
Sequence *seq,
|
|
|
|
const bool do_cache,
|
2020-04-12 22:09:46 +02:00
|
|
|
const bool do_id_user,
|
|
|
|
const bool do_clean_animdata)
|
2008-12-15 05:21:44 +00:00
|
|
|
{
|
2019-04-22 09:39:35 +10:00
|
|
|
if (seq->strip) {
|
2012-08-08 11:15:36 +00:00
|
|
|
seq_free_strip(seq->strip);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2008-12-15 05:21:44 +00:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
BKE_sequence_free_anim(seq);
|
2009-08-09 21:16:39 +00:00
|
|
|
|
2012-06-07 15:49:02 +00:00
|
|
|
if (seq->type & SEQ_TYPE_EFFECT) {
|
2012-08-08 11:15:40 +00:00
|
|
|
struct SeqEffectHandle sh = BKE_sequence_get_effect(seq);
|
2018-12-28 13:37:51 +01:00
|
|
|
sh.free(seq, do_id_user);
|
2009-07-08 17:41:45 +00:00
|
|
|
}
|
2008-12-15 05:21:44 +00:00
|
|
|
|
2018-05-11 11:21:30 +02:00
|
|
|
if (seq->sound && do_id_user) {
|
2015-11-09 19:47:10 +01:00
|
|
|
id_us_min(((ID *)seq->sound));
|
2011-05-16 17:14:47 +00:00
|
|
|
}
|
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
if (seq->stereo3d_format) {
|
|
|
|
MEM_freeN(seq->stereo3d_format);
|
|
|
|
}
|
|
|
|
|
2012-12-17 08:45:44 +00:00
|
|
|
/* clipboard has no scene and will never have a sound handle or be active
|
|
|
|
* same goes to sequences copy for proxy rebuild job
|
|
|
|
*/
|
2012-03-24 06:18:31 +00:00
|
|
|
if (scene) {
|
2009-12-17 16:28:45 +00:00
|
|
|
Editing *ed = scene->ed;
|
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (ed->act_seq == seq) {
|
2012-03-29 22:26:11 +00:00
|
|
|
ed->act_seq = NULL;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2009-12-17 16:28:45 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (seq->scene_sound && ELEM(seq->type, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SCENE)) {
|
2015-03-26 11:35:41 +01:00
|
|
|
BKE_sound_remove_scene_sound(scene, seq->scene_sound);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2008-12-15 05:21:44 +00:00
|
|
|
|
2020-04-12 22:09:46 +02:00
|
|
|
/* XXX This must not be done in BKE code. */
|
|
|
|
if (do_clean_animdata) {
|
|
|
|
seq_free_animdata(scene, seq);
|
|
|
|
}
|
2010-07-13 09:31:28 +00:00
|
|
|
}
|
2010-07-03 21:13:08 +00:00
|
|
|
|
2015-04-02 21:05:12 +11:00
|
|
|
if (seq->prop) {
|
2019-05-16 14:17:11 +02:00
|
|
|
IDP_FreePropertyContent_ex(seq->prop, do_id_user);
|
2015-04-02 21:05:12 +11:00
|
|
|
MEM_freeN(seq->prop);
|
|
|
|
}
|
|
|
|
|
2012-08-19 15:41:56 +00:00
|
|
|
/* free modifiers */
|
2012-08-20 10:15:32 +00:00
|
|
|
BKE_sequence_modifier_clear(seq);
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2012-08-27 09:01:36 +00:00
|
|
|
/* free cached data used by this strip,
|
|
|
|
* also invalidate cache for all dependent sequences
|
2012-09-06 04:45:25 +00:00
|
|
|
*
|
|
|
|
* be _very_ careful here, invalidating cache loops over the scene sequences and
|
2019-04-27 12:07:07 +10:00
|
|
|
* assumes the listbase is valid for all strips,
|
|
|
|
* this may not be the case if lists are being freed.
|
2012-09-06 04:45:25 +00:00
|
|
|
* this is optional BKE_sequence_invalidate_cache
|
2012-08-27 09:01:36 +00:00
|
|
|
*/
|
2012-09-06 04:45:25 +00:00
|
|
|
if (do_cache) {
|
|
|
|
if (scene) {
|
2019-05-23 11:52:28 -07:00
|
|
|
BKE_sequence_invalidate_cache_raw(scene, seq);
|
2012-09-06 04:45:25 +00:00
|
|
|
}
|
|
|
|
}
|
2012-08-12 18:24:01 +00:00
|
|
|
|
2008-12-15 05:21:44 +00:00
|
|
|
MEM_freeN(seq);
|
|
|
|
}
|
|
|
|
|
2020-04-12 22:09:46 +02:00
|
|
|
void BKE_sequence_free(Scene *scene, Sequence *seq, const bool do_clean_animdata)
|
2012-09-06 09:23:38 +00:00
|
|
|
{
|
2020-04-12 22:09:46 +02:00
|
|
|
BKE_sequence_free_ex(scene, seq, true, true, do_clean_animdata);
|
2012-09-06 09:23:38 +00:00
|
|
|
}
|
|
|
|
|
2012-09-06 04:45:25 +00:00
|
|
|
/* cache must be freed before calling this function
|
|
|
|
* since it leaves the seqbase in an invalid state */
|
2020-11-05 13:33:27 +01:00
|
|
|
void seq_free_sequence_recurse(Scene *scene, Sequence *seq, const bool do_id_user)
|
== Sequencer ==
This patch adds:
* support for proxy building again (missing feature from Blender 2.49)
additionally to the way, Blender 2.49 worked, you can select several
strips at once and make Blender build proxies in the background (using
the job system)
Also a new thing: movie proxies are now build into AVI files, and
the proxy system is moved into ImBuf-library, so that other parts
of blender can also benefit from it.
* Timecode support: to fix seeking issues with files, that have
a) varying frame rates
b) very large GOP lengths
c) are broken inbetween
d) use different time code tracks
the proxy builder can now also build timecode indices, which are
used (optionally) for seeking.
For the first time, it is possible, to do frame exact seeking on
all file types.
* Support for different video-streams in one video file (can be
selected in sequencer, other parts of blender can also use it,
but UI has to be added accordingly)
* IMPORTANT: this patch *requires* ffmpeg 0.7 or newer, since
older versions don't support the pkt_pts field, that is essential
for building timecode indices.
Windows and Mac libs are already updated, Linux-users have to build
their own ffmpeg verions until distros keep up.
2011-08-28 14:46:03 +00:00
|
|
|
{
|
2012-09-06 04:45:25 +00:00
|
|
|
Sequence *iseq, *iseq_next;
|
== Sequencer ==
This patch adds:
* support for proxy building again (missing feature from Blender 2.49)
additionally to the way, Blender 2.49 worked, you can select several
strips at once and make Blender build proxies in the background (using
the job system)
Also a new thing: movie proxies are now build into AVI files, and
the proxy system is moved into ImBuf-library, so that other parts
of blender can also benefit from it.
* Timecode support: to fix seeking issues with files, that have
a) varying frame rates
b) very large GOP lengths
c) are broken inbetween
d) use different time code tracks
the proxy builder can now also build timecode indices, which are
used (optionally) for seeking.
For the first time, it is possible, to do frame exact seeking on
all file types.
* Support for different video-streams in one video file (can be
selected in sequencer, other parts of blender can also use it,
but UI has to be added accordingly)
* IMPORTANT: this patch *requires* ffmpeg 0.7 or newer, since
older versions don't support the pkt_pts field, that is essential
for building timecode indices.
Windows and Mac libs are already updated, Linux-users have to build
their own ffmpeg verions until distros keep up.
2011-08-28 14:46:03 +00:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
for (iseq = seq->seqbase.first; iseq; iseq = iseq_next) {
|
|
|
|
iseq_next = iseq->next;
|
|
|
|
seq_free_sequence_recurse(scene, iseq, do_id_user);
|
2015-04-06 10:40:12 -03:00
|
|
|
}
|
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
BKE_sequence_free_ex(scene, seq, false, do_id_user, true);
|
|
|
|
}
|
2015-04-06 10:40:12 -03:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
Editing *BKE_sequencer_editing_get(Scene *scene, bool alloc)
|
|
|
|
{
|
|
|
|
if (alloc) {
|
|
|
|
BKE_sequencer_editing_ensure(scene);
|
2015-04-06 10:40:12 -03:00
|
|
|
}
|
2020-11-16 05:02:30 +01:00
|
|
|
return scene->ed;
|
|
|
|
}
|
2019-09-29 16:17:48 -07:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
Editing *BKE_sequencer_editing_ensure(Scene *scene)
|
|
|
|
{
|
|
|
|
if (scene->ed == NULL) {
|
|
|
|
Editing *ed;
|
2015-04-06 10:40:12 -03:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
ed = scene->ed = MEM_callocN(sizeof(Editing), "addseq");
|
|
|
|
ed->seqbasep = &ed->seqbase;
|
|
|
|
ed->cache = NULL;
|
|
|
|
ed->cache_flag = SEQ_CACHE_STORE_FINAL_OUT;
|
|
|
|
ed->cache_flag |= SEQ_CACHE_VIEW_FINAL_OUT;
|
|
|
|
ed->cache_flag |= SEQ_CACHE_VIEW_ENABLE;
|
|
|
|
ed->recycle_max_cost = 10.0f;
|
2015-04-06 10:40:12 -03:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
return scene->ed;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
void BKE_sequencer_editing_free(Scene *scene, const bool do_id_user)
|
|
|
|
{
|
|
|
|
Editing *ed = scene->ed;
|
|
|
|
Sequence *seq;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
if (ed == NULL) {
|
|
|
|
return;
|
2016-01-08 18:30:26 +13:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
BKE_sequencer_prefetch_free(scene);
|
|
|
|
BKE_sequencer_cache_destruct(scene);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
SEQ_ALL_BEGIN (ed, seq) {
|
|
|
|
/* handle cache freeing above */
|
|
|
|
BKE_sequence_free_ex(scene, seq, false, do_id_user, false);
|
|
|
|
}
|
|
|
|
SEQ_ALL_END;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
BLI_freelistN(&ed->metastack);
|
|
|
|
MEM_freeN(ed);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
scene->ed = NULL;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
static void seq_new_fix_links_recursive(Sequence *seq)
|
|
|
|
{
|
|
|
|
SequenceModifierData *smd;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
if (seq->type & SEQ_TYPE_EFFECT) {
|
|
|
|
if (seq->seq1 && seq->seq1->tmp) {
|
|
|
|
seq->seq1 = seq->seq1->tmp;
|
|
|
|
}
|
|
|
|
if (seq->seq2 && seq->seq2->tmp) {
|
|
|
|
seq->seq2 = seq->seq2->tmp;
|
|
|
|
}
|
|
|
|
if (seq->seq3 && seq->seq3->tmp) {
|
|
|
|
seq->seq3 = seq->seq3->tmp;
|
|
|
|
}
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2020-11-16 05:02:30 +01:00
|
|
|
else if (seq->type == SEQ_TYPE_META) {
|
|
|
|
Sequence *seqn;
|
|
|
|
for (seqn = seq->seqbase.first; seqn; seqn = seqn->next) {
|
|
|
|
seq_new_fix_links_recursive(seqn);
|
|
|
|
}
|
2009-11-14 19:26:58 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
for (smd = seq->modifiers.first; smd; smd = smd->next) {
|
|
|
|
if (smd->mask_sequence && smd->mask_sequence->tmp) {
|
|
|
|
smd->mask_sequence = smd->mask_sequence->tmp;
|
|
|
|
}
|
|
|
|
}
|
2009-11-14 19:26:58 +00:00
|
|
|
}
|
2020-12-16 20:34:26 +01:00
|
|
|
|
|
|
|
SequencerToolSettings *SEQ_tool_settings_init(void)
|
|
|
|
{
|
|
|
|
SequencerToolSettings *tool_settings = MEM_callocN(sizeof(SequencerToolSettings),
|
|
|
|
"Sequencer tool settings");
|
|
|
|
tool_settings->fit_method = SEQ_SCALE_TO_FIT;
|
|
|
|
return tool_settings;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SEQ_tool_settings_free(SequencerToolSettings *tool_settings)
|
|
|
|
{
|
|
|
|
MEM_freeN(tool_settings);
|
|
|
|
}
|
|
|
|
|
|
|
|
eSeqImageFitMethod SEQ_tool_settings_fit_method_get(Scene *scene)
|
|
|
|
{
|
|
|
|
const SequencerToolSettings *tool_settings = scene->toolsettings->sequencer_tool_settings;
|
|
|
|
return tool_settings->fit_method;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SEQ_tool_settings_fit_method_set(Scene *scene, eSeqImageFitMethod fit_method)
|
|
|
|
{
|
|
|
|
SequencerToolSettings *tool_settings = scene->toolsettings->sequencer_tool_settings;
|
|
|
|
tool_settings->fit_method = fit_method;
|
|
|
|
}
|
|
|
|
|
2020-12-17 02:11:22 +01:00
|
|
|
/**
|
|
|
|
* Get seqbase that is being viewed currently. This can be main seqbase or meta strip seqbase
|
|
|
|
*
|
|
|
|
* \param ed: sequence editor data
|
|
|
|
* \return pointer to active seqbase. returns NULL if ed is NULL
|
|
|
|
*/
|
|
|
|
ListBase *SEQ_active_seqbase_get(const Editing *ed)
|
|
|
|
{
|
|
|
|
if (ed == NULL) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ed->seqbasep;
|
|
|
|
}
|
2020-11-16 05:02:30 +01:00
|
|
|
/** \} */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
/* -------------------------------------------------------------------- */
|
2020-11-16 16:48:41 +11:00
|
|
|
/** \name Duplicate Functions
|
2020-11-16 05:02:30 +01:00
|
|
|
* \{ */
|
2019-01-11 19:48:56 +01:00
|
|
|
static Sequence *seq_dupli(const Scene *scene_src,
|
|
|
|
Scene *scene_dst,
|
|
|
|
ListBase *new_seq_list,
|
|
|
|
Sequence *seq,
|
|
|
|
int dupe_flag,
|
|
|
|
const int flag)
|
2010-06-24 10:04:18 +00:00
|
|
|
{
|
|
|
|
Sequence *seqn = MEM_dupallocN(seq);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-07-30 11:58:18 +02:00
|
|
|
if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
|
|
|
|
BKE_sequence_session_uuid_generate(seq);
|
|
|
|
}
|
|
|
|
|
2010-06-24 10:04:18 +00:00
|
|
|
seq->tmp = seqn;
|
2012-03-29 22:26:11 +00:00
|
|
|
seqn->strip = MEM_dupallocN(seq->strip);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-06 10:40:12 -03:00
|
|
|
seqn->stereo3d_format = MEM_dupallocN(seq->stereo3d_format);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-08-08 11:15:36 +00:00
|
|
|
/* XXX: add F-Curve duplication stuff? */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-06-24 10:04:18 +00:00
|
|
|
if (seq->strip->crop) {
|
|
|
|
seqn->strip->crop = MEM_dupallocN(seq->strip->crop);
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-06-24 10:04:18 +00:00
|
|
|
if (seq->strip->transform) {
|
|
|
|
seqn->strip->transform = MEM_dupallocN(seq->strip->transform);
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-06-24 10:04:18 +00:00
|
|
|
if (seq->strip->proxy) {
|
|
|
|
seqn->strip->proxy = MEM_dupallocN(seq->strip->proxy);
|
2011-02-13 10:52:18 +00:00
|
|
|
seqn->strip->proxy->anim = NULL;
|
2010-06-24 10:04:18 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-04-02 21:05:12 +11:00
|
|
|
if (seq->prop) {
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
seqn->prop = IDP_CopyProperty_ex(seq->prop, flag);
|
2015-04-02 21:05:12 +11:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-08-19 15:41:56 +00:00
|
|
|
if (seqn->modifiers.first) {
|
2014-02-08 06:07:10 +11:00
|
|
|
BLI_listbase_clear(&seqn->modifiers);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-08-19 15:41:56 +00:00
|
|
|
BKE_sequence_modifier_list_copy(seqn, seq);
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-07 15:49:02 +00:00
|
|
|
if (seq->type == SEQ_TYPE_META) {
|
2011-02-13 10:52:18 +00:00
|
|
|
seqn->strip->stripdata = NULL;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-02-08 06:07:10 +11:00
|
|
|
BLI_listbase_clear(&seqn->seqbase);
|
2010-06-24 10:04:18 +00:00
|
|
|
/* WATCH OUT!!! - This metastrip is not recursively duplicated here - do this after!!! */
|
2012-12-29 01:54:58 +00:00
|
|
|
/* - seq_dupli_recursive(&seq->seqbase, &seqn->seqbase);*/
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
2012-06-07 15:49:02 +00:00
|
|
|
else if (seq->type == SEQ_TYPE_SCENE) {
|
2011-02-13 10:52:18 +00:00
|
|
|
seqn->strip->stripdata = NULL;
|
2019-04-22 09:39:35 +10:00
|
|
|
if (seq->scene_sound) {
|
2017-08-10 13:00:01 +02:00
|
|
|
seqn->scene_sound = BKE_sound_scene_add_scene_sound_defaults(scene_dst, seqn);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
2013-07-24 07:11:00 +00:00
|
|
|
else if (seq->type == SEQ_TYPE_MOVIECLIP) {
|
|
|
|
/* avoid assert */
|
|
|
|
}
|
|
|
|
else if (seq->type == SEQ_TYPE_MASK) {
|
|
|
|
/* avoid assert */
|
|
|
|
}
|
2012-06-07 15:49:02 +00:00
|
|
|
else if (seq->type == SEQ_TYPE_MOVIE) {
|
2012-03-29 22:26:11 +00:00
|
|
|
seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata);
|
2015-04-06 10:40:12 -03:00
|
|
|
BLI_listbase_clear(&seqn->anims);
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
2012-06-07 15:49:02 +00:00
|
|
|
else if (seq->type == SEQ_TYPE_SOUND_RAM) {
|
2012-03-29 22:26:11 +00:00
|
|
|
seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata);
|
2019-06-04 16:52:48 +02:00
|
|
|
seqn->scene_sound = NULL;
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
|
|
|
|
id_us_plus((ID *)seqn->sound);
|
|
|
|
}
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
2012-06-07 15:49:02 +00:00
|
|
|
else if (seq->type == SEQ_TYPE_IMAGE) {
|
2012-03-29 22:26:11 +00:00
|
|
|
seqn->strip->stripdata = MEM_dupallocN(seq->strip->stripdata);
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
2015-07-01 17:32:56 +02:00
|
|
|
else if (seq->type & SEQ_TYPE_EFFECT) {
|
|
|
|
struct SeqEffectHandle sh;
|
|
|
|
sh = BKE_sequence_get_effect(seq);
|
2019-04-22 09:39:35 +10:00
|
|
|
if (sh.copy) {
|
2020-07-16 02:24:37 +02:00
|
|
|
sh.copy(seqn, seq, flag);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2011-02-13 10:52:18 +00:00
|
|
|
seqn->strip->stripdata = NULL;
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
|
|
|
else {
|
2013-07-24 07:11:00 +00:00
|
|
|
/* sequence type not handled in duplicate! Expect a crash now... */
|
|
|
|
BLI_assert(0);
|
2010-06-24 10:04:18 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-01-11 19:48:56 +01:00
|
|
|
/* When using SEQ_DUPE_UNIQUE_NAME, it is mandatory to add new sequences in relevant container
|
|
|
|
* (scene or meta's one), *before* checking for unique names. Otherwise the meta's list is empty
|
|
|
|
* and hence we miss all seqs in that meta that have already been duplicated (see T55668).
|
2019-08-01 13:53:25 +10:00
|
|
|
* Note that unique name check itself could be done at a later step in calling code, once all
|
2019-04-27 12:07:07 +10:00
|
|
|
* seqs have bee duplicated (that was first, simpler solution), but then handling of animation
|
|
|
|
* data will be broken (see T60194). */
|
2019-01-11 19:48:56 +01:00
|
|
|
if (new_seq_list != NULL) {
|
|
|
|
BLI_addtail(new_seq_list, seqn);
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-10 13:00:01 +02:00
|
|
|
if (scene_src == scene_dst) {
|
2017-08-10 12:56:32 +02:00
|
|
|
if (dupe_flag & SEQ_DUPE_UNIQUE_NAME) {
|
2017-08-10 13:00:01 +02:00
|
|
|
BKE_sequence_base_unique_name_recursive(&scene_dst->ed->seqbase, seqn);
|
2017-08-10 12:56:32 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-08-10 12:56:32 +02:00
|
|
|
if (dupe_flag & SEQ_DUPE_ANIM) {
|
2017-08-10 13:00:01 +02:00
|
|
|
BKE_sequencer_dupe_animdata(scene_dst, seq->name + 2, seqn->name + 2);
|
2017-08-10 12:56:32 +02:00
|
|
|
}
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-06-24 10:04:18 +00:00
|
|
|
return seqn;
|
|
|
|
}
|
|
|
|
|
2019-01-11 19:48:56 +01:00
|
|
|
static Sequence *sequence_dupli_recursive_do(const Scene *scene_src,
|
|
|
|
Scene *scene_dst,
|
|
|
|
ListBase *new_seq_list,
|
|
|
|
Sequence *seq,
|
|
|
|
const int dupe_flag)
|
2010-06-24 10:04:18 +00:00
|
|
|
{
|
2015-08-05 20:18:57 +10:00
|
|
|
Sequence *seqn;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2015-08-05 20:18:57 +10:00
|
|
|
seq->tmp = NULL;
|
2019-01-11 19:48:56 +01:00
|
|
|
seqn = seq_dupli(scene_src, scene_dst, new_seq_list, seq, dupe_flag, 0);
|
2012-06-07 15:49:02 +00:00
|
|
|
if (seq->type == SEQ_TYPE_META) {
|
2010-06-25 12:04:04 +00:00
|
|
|
Sequence *s;
|
2012-03-29 22:26:11 +00:00
|
|
|
for (s = seq->seqbase.first; s; s = s->next) {
|
2019-01-11 19:48:56 +01:00
|
|
|
sequence_dupli_recursive_do(scene_src, scene_dst, &seqn->seqbase, s, dupe_flag);
|
2010-06-24 10:04:18 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
2019-01-11 19:48:56 +01:00
|
|
|
return seqn;
|
|
|
|
}
|
|
|
|
|
|
|
|
Sequence *BKE_sequence_dupli_recursive(
|
|
|
|
const Scene *scene_src, Scene *scene_dst, ListBase *new_seq_list, Sequence *seq, int dupe_flag)
|
|
|
|
{
|
|
|
|
Sequence *seqn = sequence_dupli_recursive_do(scene_src, scene_dst, new_seq_list, seq, dupe_flag);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-01-11 19:48:56 +01:00
|
|
|
/* This does not need to be in recursive call itself, since it is already recursive... */
|
2015-04-20 11:51:43 +02:00
|
|
|
seq_new_fix_links_recursive(seqn);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2010-06-24 10:04:18 +00:00
|
|
|
return seqn;
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-10-21 11:10:45 +02:00
|
|
|
void BKE_sequence_base_dupli_recursive(const Scene *scene_src,
|
2017-08-10 15:06:53 +02:00
|
|
|
Scene *scene_dst,
|
|
|
|
ListBase *nseqbase,
|
|
|
|
const ListBase *seqbase,
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
int dupe_flag,
|
|
|
|
const int flag)
|
2010-06-24 10:04:18 +00:00
|
|
|
{
|
|
|
|
Sequence *seq;
|
2011-02-13 10:52:18 +00:00
|
|
|
Sequence *seqn = NULL;
|
2017-08-10 15:06:53 +02:00
|
|
|
Sequence *last_seq = BKE_sequencer_active_get((Scene *)scene_src);
|
2014-10-21 11:10:45 +02:00
|
|
|
/* always include meta's strips */
|
2020-04-26 23:35:56 +02:00
|
|
|
int dupe_flag_recursive = dupe_flag | SEQ_DUPE_ALL | SEQ_DUPE_IS_RECURSIVE_CALL;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-29 22:26:11 +00:00
|
|
|
for (seq = seqbase->first; seq; seq = seq->next) {
|
|
|
|
seq->tmp = NULL;
|
2012-03-24 06:18:31 +00:00
|
|
|
if ((seq->flag & SELECT) || (dupe_flag & SEQ_DUPE_ALL)) {
|
2019-01-11 19:48:56 +01:00
|
|
|
seqn = seq_dupli(scene_src, scene_dst, nseqbase, seq, dupe_flag, flag);
|
2010-06-24 10:04:18 +00:00
|
|
|
if (seqn) { /*should never fail */
|
2012-03-24 06:18:31 +00:00
|
|
|
if (dupe_flag & SEQ_DUPE_CONTEXT) {
|
2010-06-24 10:04:18 +00:00
|
|
|
seq->flag &= ~SEQ_ALLSEL;
|
2012-03-29 22:26:11 +00:00
|
|
|
seqn->flag &= ~(SEQ_LEFTSEL + SEQ_RIGHTSEL + SEQ_LOCK);
|
2010-06-24 10:04:18 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-10-21 11:10:45 +02:00
|
|
|
if (seq->type == SEQ_TYPE_META) {
|
|
|
|
BKE_sequence_base_dupli_recursive(
|
2017-08-10 15:06:53 +02:00
|
|
|
scene_src, scene_dst, &seqn->seqbase, &seq->seqbase, dupe_flag_recursive, flag);
|
2014-10-21 11:10:45 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-24 06:18:31 +00:00
|
|
|
if (dupe_flag & SEQ_DUPE_CONTEXT) {
|
2010-06-24 10:04:18 +00:00
|
|
|
if (seq == last_seq) {
|
2017-08-10 15:06:53 +02:00
|
|
|
BKE_sequencer_active_set(scene_dst, seqn);
|
2010-06-24 10:04:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-04-26 23:35:56 +02:00
|
|
|
/* Fix modifier links recursively from the top level only, when all sequences have been
|
|
|
|
* copied. */
|
|
|
|
if (dupe_flag & SEQ_DUPE_IS_RECURSIVE_CALL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-04-20 11:51:43 +02:00
|
|
|
/* fix modifier linking */
|
|
|
|
for (seq = nseqbase->first; seq; seq = seq->next) {
|
|
|
|
seq_new_fix_links_recursive(seq);
|
|
|
|
}
|
2010-06-24 10:04:18 +00:00
|
|
|
}
|
2020-11-16 05:02:30 +01:00
|
|
|
/* r_prefix + [" + escaped_name + "] + \0 */
|
|
|
|
#define SEQ_RNAPATH_MAXSTR ((30 + 2 + (SEQ_NAME_MAXSTR * 2) + 2) + 1)
|
2012-08-13 17:36:29 +00:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
static size_t sequencer_rna_path_prefix(char str[SEQ_RNAPATH_MAXSTR], const char *name)
|
2012-08-13 17:36:29 +00:00
|
|
|
{
|
2020-11-16 05:02:30 +01:00
|
|
|
char name_esc[SEQ_NAME_MAXSTR * 2];
|
2012-08-13 17:36:29 +00:00
|
|
|
|
2020-12-10 13:25:49 +11:00
|
|
|
BLI_str_escape(name_esc, name, sizeof(name_esc));
|
2020-11-16 05:02:30 +01:00
|
|
|
return BLI_snprintf_rlen(
|
|
|
|
str, SEQ_RNAPATH_MAXSTR, "sequence_editor.sequences_all[\"%s\"]", name_esc);
|
2012-08-13 17:36:29 +00:00
|
|
|
}
|
2012-08-19 15:41:56 +00:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
/* XXX - hackish function needed for transforming strips! TODO - have some better solution */
|
|
|
|
void BKE_sequencer_offset_animdata(Scene *scene, Sequence *seq, int ofs)
|
2014-11-24 18:18:35 +01:00
|
|
|
{
|
2020-11-16 05:02:30 +01:00
|
|
|
char str[SEQ_RNAPATH_MAXSTR];
|
|
|
|
size_t str_len;
|
|
|
|
FCurve *fcu;
|
2014-11-24 18:18:35 +01:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
if (scene->adt == NULL || ofs == 0 || scene->adt->action == NULL) {
|
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2014-11-24 18:18:35 +01:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
str_len = sequencer_rna_path_prefix(str, seq->name + 2);
|
2014-11-24 18:18:35 +01:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
for (fcu = scene->adt->action->curves.first; fcu; fcu = fcu->next) {
|
|
|
|
if (STREQLEN(fcu->rna_path, str, str_len)) {
|
|
|
|
unsigned int i;
|
|
|
|
if (fcu->bezt) {
|
|
|
|
for (i = 0; i < fcu->totvert; i++) {
|
|
|
|
BezTriple *bezt = &fcu->bezt[i];
|
|
|
|
bezt->vec[0][0] += ofs;
|
|
|
|
bezt->vec[1][0] += ofs;
|
|
|
|
bezt->vec[2][0] += ofs;
|
|
|
|
}
|
2014-11-24 18:18:35 +01:00
|
|
|
}
|
2020-11-16 05:02:30 +01:00
|
|
|
if (fcu->fpt) {
|
|
|
|
for (i = 0; i < fcu->totvert; i++) {
|
|
|
|
FPoint *fpt = &fcu->fpt[i];
|
|
|
|
fpt->vec[0] += ofs;
|
|
|
|
}
|
2014-11-24 18:18:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
DEG_id_tag_update(&scene->adt->action->id, ID_RECALC_ANIMATION);
|
2014-11-24 18:18:35 +01:00
|
|
|
}
|
2016-08-09 14:33:00 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
void BKE_sequencer_dupe_animdata(Scene *scene, const char *name_src, const char *name_dst)
|
2016-08-09 14:33:00 +02:00
|
|
|
{
|
2020-11-16 05:02:30 +01:00
|
|
|
char str_from[SEQ_RNAPATH_MAXSTR];
|
|
|
|
size_t str_from_len;
|
|
|
|
FCurve *fcu;
|
|
|
|
FCurve *fcu_last;
|
|
|
|
FCurve *fcu_cpy;
|
|
|
|
ListBase lb = {NULL, NULL};
|
2016-08-09 14:33:00 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
if (scene->adt == NULL || scene->adt->action == NULL) {
|
2019-05-01 05:16:01 -07:00
|
|
|
return;
|
2016-08-09 14:33:00 +02:00
|
|
|
}
|
2020-05-10 07:50:09 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
str_from_len = sequencer_rna_path_prefix(str_from, name_src);
|
2020-05-10 07:50:09 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
fcu_last = scene->adt->action->curves.last;
|
2020-05-10 07:50:09 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
for (fcu = scene->adt->action->curves.first; fcu && fcu->prev != fcu_last; fcu = fcu->next) {
|
|
|
|
if (STREQLEN(fcu->rna_path, str_from, str_from_len)) {
|
|
|
|
fcu_cpy = BKE_fcurve_copy(fcu);
|
|
|
|
BLI_addtail(&lb, fcu_cpy);
|
2020-05-10 07:50:09 +02:00
|
|
|
}
|
2020-07-26 14:58:44 +02:00
|
|
|
}
|
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
/* notice validate is 0, keep this because the seq may not be added to the scene yet */
|
|
|
|
BKE_animdata_fix_paths_rename(
|
|
|
|
&scene->id, scene->adt, NULL, "sequence_editor.sequences_all", name_src, name_dst, 0, 0, 0);
|
2020-07-26 14:58:44 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
/* add the original fcurves back */
|
|
|
|
BLI_movelisttolist(&scene->adt->action->curves, &lb);
|
2020-07-26 14:58:44 +02:00
|
|
|
}
|
2020-07-26 16:07:34 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
/* XXX - hackish function needed to remove all fcurves belonging to a sequencer strip */
|
|
|
|
static void seq_free_animdata(Scene *scene, Sequence *seq)
|
2020-07-26 16:07:34 +02:00
|
|
|
{
|
2020-11-16 05:02:30 +01:00
|
|
|
char str[SEQ_RNAPATH_MAXSTR];
|
|
|
|
size_t str_len;
|
|
|
|
FCurve *fcu;
|
2020-07-26 16:07:34 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
if (scene->adt == NULL || scene->adt->action == NULL) {
|
2020-07-26 16:07:34 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
str_len = sequencer_rna_path_prefix(str, seq->name + 2);
|
2020-07-26 16:07:34 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
fcu = scene->adt->action->curves.first;
|
2020-07-31 11:53:22 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
while (fcu) {
|
|
|
|
if (STREQLEN(fcu->rna_path, str, str_len)) {
|
|
|
|
FCurve *next_fcu = fcu->next;
|
2020-07-30 12:23:37 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
BLI_remlink(&scene->adt->action->curves, fcu);
|
|
|
|
BKE_fcurve_free(fcu);
|
2020-07-30 12:23:37 +02:00
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
fcu = next_fcu;
|
2020-07-30 12:23:37 +02:00
|
|
|
}
|
2020-11-16 05:02:30 +01:00
|
|
|
else {
|
|
|
|
fcu = fcu->next;
|
2020-07-30 12:23:37 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-11-16 05:02:30 +01:00
|
|
|
|
|
|
|
#undef SEQ_RNAPATH_MAXSTR
|
2020-12-16 20:34:26 +01:00
|
|
|
|
|
|
|
SequencerToolSettings *SEQ_tool_settings_copy(SequencerToolSettings *tool_settings)
|
|
|
|
{
|
|
|
|
SequencerToolSettings *tool_settings_copy = MEM_dupallocN(tool_settings);
|
|
|
|
return tool_settings_copy;
|
|
|
|
}
|
|
|
|
|
2020-11-16 05:02:30 +01:00
|
|
|
/** \} */
|