CID: 595 Checker: OVERRUN_STATIC (help) File: base/src/source/blender/python/api2_2x/sceneSequence.c Function: Sequence_setProxyDir Description: Overrun of static array "&((((self)->seq)->strip)->proxy)->dir" of size 160 bytes by passing it to a function which indexes it with argument "248" at byte position 247 Wasn't using the size of dir it was using the sizeof the struct dir is in. Fixed. Kent
1923 lines
49 KiB
C
1923 lines
49 KiB
C
/*
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
*
|
|
* 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,
|
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
*
|
|
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
|
* All rights reserved.
|
|
*
|
|
* This is a new part of Blender.
|
|
*
|
|
* Contributor(s): Campbell Barton
|
|
*
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
*/
|
|
|
|
#include "sceneSequence.h" /* This must come first */
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "DNA_sequence_types.h"
|
|
#include "DNA_scene_types.h" /* for Base */
|
|
|
|
#include "BKE_mesh.h"
|
|
#include "BKE_image.h" // RFS: openanim
|
|
#include "BKE_library.h"
|
|
#include "BKE_global.h"
|
|
#include "BKE_main.h"
|
|
#include "BKE_scene.h"
|
|
|
|
#include "BIF_editseq.h" /* get_last_seq */
|
|
#include "BIF_editsound.h" // RFS: sound_open_hdaudio
|
|
#include "BLI_blenlib.h"
|
|
#include "BSE_sequence.h"
|
|
#include "BSE_seqeffects.h"
|
|
#include "Ipo.h"
|
|
#include "blendef.h" /* CLAMP */
|
|
#include "BKE_utildefines.h"
|
|
#include "Scene.h"
|
|
#include "Sound.h"
|
|
#include "gen_utils.h"
|
|
|
|
#include "IMB_imbuf_types.h" // RFS: IB_rect
|
|
#include "IMB_imbuf.h" // RFS: IMB_anim_get_duration
|
|
|
|
enum seq_consts
|
|
{
|
|
EXPP_SEQ_ATTR_TYPE = 0,
|
|
EXPP_SEQ_ATTR_CHAN,
|
|
EXPP_SEQ_ATTR_LENGTH,
|
|
EXPP_SEQ_ATTR_START,
|
|
EXPP_SEQ_ATTR_STARTOFS,
|
|
EXPP_SEQ_ATTR_ENDOFS,
|
|
EXPP_SEQ_ATTR_STARTSTILL,
|
|
EXPP_SEQ_ATTR_ENDSTILL,
|
|
EXPP_SEQ_ATTR_STARTDISP,
|
|
EXPP_SEQ_ATTR_ENDDISP
|
|
};
|
|
|
|
enum seq_effect_consts
|
|
{
|
|
/* speed */
|
|
EXPP_SEQ_ATTR_EFFECT_GLOBAL_SPEED,
|
|
EXPP_SEQ_ATTR_EFFECT_IPO_IS_VELOCITY,
|
|
EXPP_SEQ_ATTR_EFFECT_FRAME_BLENDING,
|
|
EXPP_SEQ_ATTR_EFFECT_NORMALIZE_IPO_0_1,
|
|
|
|
/* wipe */
|
|
EXPP_SEQ_ATTR_EFFECT_ANGLE,
|
|
EXPP_SEQ_ATTR_EFFECT_BLUR,
|
|
EXPP_SEQ_ATTR_EFFECT_WIPE_IN
|
|
};
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Python API function prototypes for the Blender module. */
|
|
/*****************************************************************************/
|
|
/*PyObject *M_Sequence_Get( PyObject * self, PyObject * args );*/
|
|
|
|
/*****************************************************************************/
|
|
/* Python method structure definition for Blender.Object module: */
|
|
/*****************************************************************************/
|
|
/*struct PyMethodDef M_Sequence_methods[] = {
|
|
{"Get", ( PyCFunction ) M_Sequence_Get, METH_VARARGS,
|
|
"(name) - return the sequence with the name 'name',\
|
|
returns None if notfound.\nIf 'name' is not specified, it returns a list of all sequences."},
|
|
{NULL, NULL, 0, NULL}
|
|
};*/
|
|
|
|
/*****************************************************************************/
|
|
/* Python BPy_Sequence methods table: */
|
|
/*****************************************************************************/
|
|
static PyObject *Sequence_copy(BPy_Sequence * self);
|
|
static PyObject *Sequence_update(BPy_Sequence * self, PyObject *args);
|
|
static PyObject *Sequence_new(BPy_Sequence * self, PyObject * args);
|
|
static PyObject *Sequence_remove(BPy_Sequence * self, PyObject * args);
|
|
static PyObject *Sequence_rebuildProxy(BPy_Sequence * self);
|
|
|
|
static PyObject *SceneSeq_new(BPy_SceneSeq * self, PyObject * args);
|
|
static PyObject *SceneSeq_remove(BPy_SceneSeq * self, PyObject * args);
|
|
static void intern_pos_update(Sequence * seq);
|
|
|
|
static PyMethodDef BPy_Sequence_methods[] = {
|
|
/* name, method, flags, doc */
|
|
{"new", (PyCFunction) Sequence_new, METH_VARARGS,
|
|
"(data) - Return a new sequence."},
|
|
{"remove", (PyCFunction) Sequence_remove, METH_VARARGS,
|
|
"(data) - Remove a strip."},
|
|
{"__copy__", (PyCFunction) Sequence_copy, METH_NOARGS,
|
|
"() - Return a copy of the sequence containing the same objects."},
|
|
{"copy", (PyCFunction) Sequence_copy, METH_NOARGS,
|
|
"() - Return a copy of the sequence containing the same objects."},
|
|
{"update", (PyCFunction) Sequence_update, METH_VARARGS,
|
|
"() - Force and update of the sequence strip"},
|
|
{"rebuildProxy", (PyCFunction) Sequence_rebuildProxy, METH_VARARGS,
|
|
"() - Rebuild the active strip's Proxy."},
|
|
{NULL, NULL, 0, NULL}
|
|
};
|
|
|
|
static PyMethodDef BPy_SceneSeq_methods[] = {
|
|
/* name, method, flags, doc */
|
|
{"new", (PyCFunction) SceneSeq_new, METH_VARARGS,
|
|
"(data) - Return a new sequence."},
|
|
{"remove", (PyCFunction) SceneSeq_remove, METH_VARARGS,
|
|
"(data) - Remove a strip."},
|
|
{NULL, NULL, 0, NULL}
|
|
};
|
|
|
|
/* use to add a sequence to a scene or its listbase */
|
|
static PyObject *NewSeq_internal(ListBase *seqbase, PyObject * args, Scene *sce)
|
|
{
|
|
PyObject *py_data = NULL;
|
|
|
|
Sequence *seq;
|
|
PyObject *pyob1 = NULL, *pyob2 = NULL, *pyob3 = NULL; /* for effects */
|
|
int type;
|
|
|
|
int a;
|
|
Strip *strip;
|
|
StripElem *se;
|
|
int start, machine;
|
|
|
|
if (!PyArg_ParseTuple(args, "Oii", &py_data, &start, &machine))
|
|
return EXPP_ReturnPyObjError(PyExc_ValueError,
|
|
"expect sequence data then 2 ints - (seqdata, start, track)");
|
|
|
|
if (machine < 1 || machine >= MAXSEQ)
|
|
{
|
|
return EXPP_ReturnPyObjError(PyExc_ValueError,
|
|
"track out of range");
|
|
}
|
|
|
|
seq = alloc_sequence(seqbase, start, machine); /* warning, this sets last */
|
|
|
|
|
|
if (PyList_Check(py_data)) /* new metastrip, list of seqs */
|
|
{
|
|
/* Warning, no checks for audio which should not be allowed, or a blank metaseq if an empty list */
|
|
int fail= 0;
|
|
Sequence *seq_iter;
|
|
PyObject *item;
|
|
seq->type= SEQ_META;
|
|
|
|
|
|
for(a=PyList_GET_SIZE(py_data)-1; a >= 0; a--) {
|
|
item= PyList_GET_ITEM(py_data, a);
|
|
if (!BPy_Sequence_Check(item)) { /* ignore non seq types */
|
|
fail= 1;
|
|
break;
|
|
}
|
|
|
|
seq_iter = ((BPy_Sequence *) item)->seq;
|
|
if (BLI_findindex(seqbase, seq_iter) == -1) {
|
|
fail= 2;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (fail) {
|
|
BLI_remlink(seqbase, seq);
|
|
free_sequence(seq);
|
|
|
|
if (fail==1)
|
|
return EXPP_ReturnPyObjError(PyExc_ValueError, "One of more of the list items was not a sequence strip");
|
|
else
|
|
return EXPP_ReturnPyObjError(PyExc_ValueError, "One of more of the list items sequence strips is not in this meta or scene");
|
|
}
|
|
|
|
|
|
for(a=PyList_GET_SIZE(py_data)-1; a >= 0; a--) {
|
|
item= PyList_GET_ITEM(py_data, a);
|
|
seq_iter = ((BPy_Sequence *) item)->seq;
|
|
BLI_remlink(seqbase, seq_iter);
|
|
BLI_addtail(&seq->seqbase, seq_iter);
|
|
}
|
|
|
|
clear_last_seq(); /* just incase */
|
|
calc_sequence(seq);
|
|
|
|
seq->strip= MEM_callocN(sizeof(Strip), "metastrip");
|
|
seq->strip->len= seq->len;
|
|
seq->strip->us= 1;
|
|
}
|
|
else if (PyTuple_Check(py_data) && PyTuple_GET_SIZE(py_data) >= 2 && BPy_Sequence_Check(PyTuple_GET_ITEM(py_data, 1)))
|
|
{
|
|
|
|
struct SeqEffectHandle sh;
|
|
Sequence *seq1, *seq2 = NULL, *seq3 = NULL; /* for effects */
|
|
|
|
if (!PyArg_ParseTuple(py_data, "iO!|O!O!", &type, &Sequence_Type, &pyob1, &Sequence_Type, &pyob2, &Sequence_Type, &pyob3))
|
|
{
|
|
BLI_remlink(seqbase, seq);
|
|
free_sequence(seq);
|
|
|
|
return EXPP_ReturnPyObjError(PyExc_ValueError,
|
|
"effect stripts expected an effect type int and 1 to 3 sequence strips");
|
|
}
|
|
|
|
|
|
seq1 = ((BPy_Sequence *) pyob1)->seq;
|
|
if (pyob2) seq2 = ((BPy_Sequence *) pyob2)->seq;
|
|
if (pyob3) seq3 = ((BPy_Sequence *) pyob3)->seq;
|
|
|
|
if (type <= SEQ_EFFECT || type > SEQ_EFFECT_MAX || type == SEQ_PLUGIN)
|
|
{
|
|
BLI_remlink(seqbase, seq);
|
|
free_sequence(seq);
|
|
|
|
return EXPP_ReturnPyObjError(PyExc_ValueError,
|
|
"sequencer type out of range, expected a value from 9 to 29, plugins not supported");
|
|
}
|
|
|
|
|
|
if (BLI_findindex(seqbase, seq1) == -1 || (seq2 && BLI_findindex(seqbase, seq2) == -1) || (seq3 && BLI_findindex(seqbase, seq3) == -1))
|
|
{
|
|
BLI_remlink(seqbase, seq);
|
|
free_sequence(seq);
|
|
|
|
return EXPP_ReturnPyObjError(PyExc_ValueError,
|
|
"one of the given effect sequences wasnt in accessible at the same level as the sequence being added");
|
|
}
|
|
|
|
if ((seq2 && seq2 == seq1) || (seq3 && (seq3 == seq1 || seq3 == seq2)))
|
|
{
|
|
BLI_remlink(seqbase, seq);
|
|
free_sequence(seq);
|
|
|
|
return EXPP_ReturnPyObjError(PyExc_ValueError,
|
|
"2 or more of the sequence arguments were the same");
|
|
|
|
}
|
|
|
|
/* allocate and initialize */
|
|
seq->type = type;
|
|
|
|
sh = get_sequence_effect(seq);
|
|
|
|
seq->seq1 = seq1;
|
|
seq->seq2 = seq2;
|
|
seq->seq3 = seq3;
|
|
|
|
sh.init(seq);
|
|
|
|
if (!seq1)
|
|
{
|
|
seq->len = 1;
|
|
seq->startstill = 25;
|
|
seq->endstill = 24;
|
|
}
|
|
|
|
calc_sequence(seq);
|
|
|
|
seq->strip = strip = MEM_callocN(sizeof (Strip), "strip");
|
|
strip->len = seq->len;
|
|
strip->us = 1;
|
|
if (seq->len > 0)
|
|
strip->stripdata = MEM_callocN(seq->len * sizeof (StripElem), "stripelem");
|
|
|
|
#if 0
|
|
/* initialize plugin */
|
|
if (newseq->type == SEQ_PLUGIN)
|
|
{
|
|
sh.init_plugin(seq, str);
|
|
|
|
if (newseq->plugin == 0)
|
|
{
|
|
BLI_remlink(ed->seqbasep, seq);
|
|
free_sequence(seq);
|
|
return 0;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
update_changed_seq_and_deps(seq, 1, 1);
|
|
|
|
}
|
|
else if (PyTuple_Check(py_data) && PyTuple_GET_SIZE(py_data) == 2)
|
|
{
|
|
/* Image */
|
|
PyObject *list;
|
|
char *name;
|
|
|
|
if (!PyArg_ParseTuple(py_data, "sO!", &name, &PyList_Type, &list))
|
|
{
|
|
BLI_remlink(seqbase, seq);
|
|
free_sequence(seq);
|
|
|
|
return EXPP_ReturnPyObjError(PyExc_ValueError,
|
|
"images data needs to be a tuple of a string and a list of images - (path, [filenames...])");
|
|
}
|
|
|
|
seq->type = SEQ_IMAGE;
|
|
|
|
seq->len = PyList_Size(list);
|
|
|
|
/* strip and stripdata */
|
|
seq->strip = strip = MEM_callocN(sizeof (Strip), "strip");
|
|
strip->len = seq->len;
|
|
strip->us = 1;
|
|
strncpy(strip->dir, name, FILE_MAXDIR - 1);
|
|
strip->stripdata = se = MEM_callocN(seq->len * sizeof (StripElem), "stripelem");
|
|
|
|
for (a = 0; a < seq->len; a++)
|
|
{
|
|
name = PyString_AsString(PyList_GetItem(list, a));
|
|
strncpy(se->name, name, FILE_MAXFILE - 1);
|
|
se++;
|
|
}
|
|
}
|
|
else if (PyTuple_Check(py_data) && PyTuple_GET_SIZE(py_data) == 3)
|
|
{
|
|
float r, g, b;
|
|
SolidColorVars *colvars;
|
|
|
|
if (!PyArg_ParseTuple(py_data, "fff", &r, &g, &b))
|
|
{
|
|
BLI_remlink(seqbase, seq);
|
|
free_sequence(seq);
|
|
return EXPP_ReturnPyObjError(PyExc_ValueError,
|
|
"color needs to be a tuple of 3 floats - (r,g,b)");
|
|
}
|
|
|
|
seq->effectdata = MEM_callocN(sizeof (struct SolidColorVars), "solidcolor");
|
|
colvars = (SolidColorVars *) seq->effectdata;
|
|
|
|
seq->type = SEQ_COLOR;
|
|
|
|
CLAMP(r, 0, 1);
|
|
CLAMP(g, 0, 1);
|
|
CLAMP(b, 0, 1);
|
|
|
|
colvars->col[0] = r;
|
|
colvars->col[1] = b;
|
|
colvars->col[2] = g;
|
|
|
|
/* basic defaults */
|
|
seq->strip = strip = MEM_callocN(sizeof (Strip), "strip");
|
|
strip->len = seq->len = 1;
|
|
strip->us = 1;
|
|
strip->stripdata = se = MEM_callocN(seq->len * sizeof (StripElem), "stripelem");
|
|
|
|
}
|
|
else if (PyTuple_Check(py_data) && PyTuple_GET_SIZE(py_data) == 4)
|
|
{
|
|
// MOVIE or AUDIO_HD
|
|
char *filename;
|
|
char *dir;
|
|
char *fullpath;
|
|
char *type;
|
|
int totframe;
|
|
|
|
if (!PyArg_ParseTuple(py_data, "ssss", &filename, &dir, &fullpath, &type))
|
|
{
|
|
BLI_remlink(seqbase, seq);
|
|
free_sequence(seq);
|
|
|
|
return EXPP_ReturnPyObjError(PyExc_ValueError,
|
|
"movie/audio hd data needs to be a tuple of a string and a list of images - (filename, dir, fullpath, type)");
|
|
}
|
|
|
|
// RFS - Attempting to support Movie and Audio (HD) strips
|
|
#define RFS
|
|
#ifdef RFS
|
|
// Movie strips
|
|
if (strcmp(type, "movie") == 0)
|
|
{
|
|
/* open it as an animation */
|
|
struct anim * an = openanim(fullpath, IB_rect);
|
|
if (an == 0)
|
|
{
|
|
BLI_remlink(seqbase, seq);
|
|
free_sequence(seq);
|
|
|
|
return EXPP_ReturnPyObjError(PyExc_ValueError,
|
|
"invalid movie strip");
|
|
}
|
|
|
|
/* get the length in frames */
|
|
totframe = IMB_anim_get_duration(an);
|
|
|
|
/* set up sequence */
|
|
seq->type = SEQ_MOVIE;
|
|
seq->len = totframe;
|
|
seq->anim = an;
|
|
seq->anim_preseek = IMB_anim_get_preseek(an);
|
|
|
|
calc_sequence(seq);
|
|
|
|
/* strip and stripdata */
|
|
seq->strip = strip = MEM_callocN(sizeof (Strip), "strip");
|
|
strip->len = totframe;
|
|
strip->us = 1;
|
|
strncpy(strip->dir, dir, FILE_MAXDIR - 1); // ????
|
|
strip->stripdata = se = MEM_callocN(sizeof (StripElem), "stripelem");
|
|
|
|
/* name movie in first strip */
|
|
strncpy(se->name, filename, FILE_MAXFILE - 1); // ????
|
|
}
|
|
|
|
// Audio (HD) strips
|
|
if (strcmp(type, "audio_hd") == 0)
|
|
{
|
|
struct hdaudio *hdaudio;
|
|
|
|
totframe = 0;
|
|
|
|
/* is it a sound file? */
|
|
hdaudio = sound_open_hdaudio(fullpath);
|
|
if (hdaudio == 0)
|
|
{
|
|
BLI_remlink(seqbase, seq);
|
|
free_sequence(seq);
|
|
|
|
return EXPP_ReturnPyObjError(PyExc_ValueError,
|
|
fullpath);
|
|
}
|
|
|
|
totframe = sound_hdaudio_get_duration(hdaudio, FPS);
|
|
|
|
/* set up sequence */
|
|
seq->type = SEQ_HD_SOUND;
|
|
seq->len = totframe;
|
|
seq->hdaudio = hdaudio;
|
|
|
|
calc_sequence(seq);
|
|
|
|
/* strip and stripdata - same as for MOVIE */
|
|
seq->strip = strip = MEM_callocN(sizeof (Strip), "strip");
|
|
strip->len = totframe;
|
|
strip->us = 1;
|
|
strncpy(strip->dir, dir, FILE_MAXDIR - 1); // ????
|
|
strip->stripdata = se = MEM_callocN(sizeof (StripElem), "stripelem");
|
|
|
|
/* name movie in first strip */
|
|
strncpy(se->name, filename, FILE_MAXFILE - 1); // ????
|
|
}
|
|
#endif
|
|
|
|
}
|
|
else if (BPy_Sound_Check(py_data))
|
|
{
|
|
/* RAM sound */
|
|
int totframe;
|
|
bSound *sound = ((BPy_Sound *) py_data)->sound;
|
|
|
|
seq->type = SEQ_RAM_SOUND;
|
|
seq->sound = sound;
|
|
|
|
totframe = (int) (((float) (sound->streamlen - 1) / ((float) sce->audio.mixrate * 4.0))* (float) sce->r.frs_sec / sce->r.frs_sec_base);
|
|
|
|
sound->flags |= SOUND_FLAGS_SEQUENCE;
|
|
|
|
/* strip and stripdata */
|
|
seq->strip = strip = MEM_callocN(sizeof (Strip), "strip");
|
|
strip->len = totframe;
|
|
strip->us = 1;
|
|
strncpy(strip->dir, sound->name, FILE_MAXDIR - 1);
|
|
strip->stripdata = se = MEM_callocN(sizeof (StripElem), "stripelem");
|
|
|
|
/* name sound in first strip */
|
|
strncpy(se->name, sound->name, FILE_MAXFILE - 1);
|
|
|
|
}
|
|
else if (BPy_Scene_Check(py_data))
|
|
{
|
|
/* scene */
|
|
Scene *sceseq = ((BPy_Scene *) py_data)->scene;
|
|
|
|
seq->type = SEQ_SCENE;
|
|
seq->scene = sceseq;
|
|
|
|
/*seq->sfra= sce->r.sfra;*/
|
|
seq->len = sceseq->r.efra - sceseq->r.sfra + 1;
|
|
|
|
seq->strip = strip = MEM_callocN(sizeof (Strip), "strip");
|
|
strncpy(seq->name + 2, sceseq->id.name + 2,
|
|
sizeof (seq->name) - 2);
|
|
strip->len = seq->len;
|
|
strip->us = 1;
|
|
}
|
|
else
|
|
{
|
|
// RFS: REMOVED MOVIE FROM HERE
|
|
}
|
|
strncpy(seq->name + 2, "Untitled", 21);
|
|
intern_pos_update(seq);
|
|
return Sequence_CreatePyObject(seq, NULL, sce);
|
|
}
|
|
|
|
static PyObject *Sequence_new(BPy_Sequence * self, PyObject * args)
|
|
{
|
|
return NewSeq_internal(&self->seq->seqbase, args, self->scene);
|
|
}
|
|
|
|
static PyObject *SceneSeq_new(BPy_SceneSeq * self, PyObject * args)
|
|
{
|
|
return NewSeq_internal(&((Editing *) self->scene->ed)->seqbase, args, self->scene);
|
|
}
|
|
|
|
static void del_seq__internal(Sequence *seq)
|
|
{
|
|
if (seq->ipo) seq->ipo->id.us--;
|
|
|
|
if (seq->type == SEQ_RAM_SOUND && seq->sound)
|
|
seq->sound->id.us--;
|
|
free_sequence(seq);
|
|
}
|
|
|
|
static void recurs_del_seq(ListBase *lb)
|
|
{
|
|
Sequence *seq, *seqn;
|
|
|
|
seq = lb->first;
|
|
while (seq)
|
|
{
|
|
seqn = seq->next;
|
|
BLI_remlink(lb, seq);
|
|
if (seq->type == SEQ_META) recurs_del_seq(&seq->seqbase);
|
|
del_seq__internal(seq);
|
|
seq = seqn;
|
|
}
|
|
}
|
|
|
|
static PyObject *RemoveSeq_internal(ListBase *seqbase, PyObject * args, Scene *sce)
|
|
{
|
|
BPy_Sequence *bpy_seq = NULL;
|
|
|
|
if (!PyArg_ParseTuple(args, "O!", &Sequence_Type, &bpy_seq))
|
|
return EXPP_ReturnPyObjError(PyExc_ValueError,
|
|
"expects a sequence object");
|
|
|
|
/* quick way to tell if we dont have the seq */
|
|
if (sce != bpy_seq->scene)
|
|
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
|
|
"Sequence does not exist here, cannot remove");
|
|
|
|
recurs_del_seq(&bpy_seq->seq->seqbase);
|
|
del_seq__internal(bpy_seq->seq);
|
|
clear_last_seq(); /* just incase */
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
static PyObject *Sequence_remove(BPy_Sequence * self, PyObject * args)
|
|
{
|
|
return RemoveSeq_internal(&self->seq->seqbase, args, self->scene);
|
|
}
|
|
|
|
static PyObject *SceneSeq_remove(BPy_SceneSeq * self, PyObject * args)
|
|
{
|
|
return RemoveSeq_internal(&((Editing *) self->scene->ed)->seqbase, args, self->scene);
|
|
}
|
|
|
|
static PyObject *Sequence_copy(BPy_Sequence * self)
|
|
{
|
|
printf("Sequence Copy not implimented yet!\n");
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
static PyObject *Sequence_update(BPy_Sequence * self, PyObject *args)
|
|
{
|
|
int data= 0;
|
|
if (!PyArg_ParseTuple(args, "|i:update", &data))
|
|
return NULL;
|
|
|
|
if (data) {
|
|
update_changed_seq_and_deps(self->seq, 1, 1);
|
|
new_tstripdata(self->seq);
|
|
}
|
|
calc_sequence(self->seq);
|
|
calc_sequence_disp(self->seq);
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* PythonTypeObject callback function prototypes */
|
|
/*****************************************************************************/
|
|
static PyObject *Sequence_repr(BPy_Sequence * obj);
|
|
static PyObject *SceneSeq_repr(BPy_SceneSeq * obj);
|
|
static int Sequence_compare(BPy_Sequence * a, BPy_Sequence * b);
|
|
static int SceneSeq_compare(BPy_SceneSeq * a, BPy_SceneSeq * b);
|
|
|
|
/*****************************************************************************/
|
|
/* Python BPy_Sequence methods: */
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
|
static PyObject *Sequence_getIter(BPy_Sequence * self)
|
|
{
|
|
Sequence *iter = self->seq->seqbase.first;
|
|
|
|
if (!self->iter)
|
|
{
|
|
self->iter = iter;
|
|
return EXPP_incr_ret((PyObject *) self);
|
|
}
|
|
else
|
|
{
|
|
return Sequence_CreatePyObject(self->seq, iter, self->scene);
|
|
}
|
|
}
|
|
|
|
static PyObject *SceneSeq_getIter(BPy_SceneSeq * self)
|
|
{
|
|
Sequence *iter = ((Editing *) self->scene->ed)->seqbase.first;
|
|
|
|
if (!self->iter)
|
|
{
|
|
self->iter = iter;
|
|
return EXPP_incr_ret((PyObject *) self);
|
|
}
|
|
else
|
|
{
|
|
return SceneSeq_CreatePyObject(self->scene, iter);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Return next Seq
|
|
*/
|
|
static PyObject *Sequence_nextIter(BPy_Sequence * self)
|
|
{
|
|
PyObject *object;
|
|
if (!(self->iter))
|
|
{
|
|
self->iter = NULL; /* so we can add objects again */
|
|
return EXPP_ReturnPyObjError(PyExc_StopIteration,
|
|
"iterator at end");
|
|
}
|
|
|
|
object = Sequence_CreatePyObject(self->iter, NULL, self->scene);
|
|
self->iter = self->iter->next;
|
|
return object;
|
|
}
|
|
|
|
/*
|
|
* Return next Seq
|
|
*/
|
|
static PyObject *SceneSeq_nextIter(BPy_Sequence * self)
|
|
{
|
|
PyObject *object;
|
|
if (!(self->iter))
|
|
{
|
|
self->iter = NULL; /* so we can add objects again */
|
|
return EXPP_ReturnPyObjError(PyExc_StopIteration,
|
|
"iterator at end");
|
|
}
|
|
|
|
object = Sequence_CreatePyObject(self->iter, NULL, self->scene);
|
|
self->iter = self->iter->next;
|
|
return object;
|
|
}
|
|
|
|
static PyObject *Sequence_getName(BPy_Sequence * self)
|
|
{
|
|
return PyString_FromString(self->seq->name + 2);
|
|
}
|
|
|
|
static int Sequence_setName(BPy_Sequence * self, PyObject * value)
|
|
{
|
|
char *name = NULL;
|
|
|
|
name = PyString_AsString(value);
|
|
if (!name)
|
|
return EXPP_ReturnIntError(PyExc_TypeError,
|
|
"expected string argument");
|
|
|
|
strncpy(self->seq->name + 2, name, 21);
|
|
return 0;
|
|
}
|
|
|
|
static PyObject *Sequence_getProxyDir(BPy_Sequence * self)
|
|
{
|
|
return PyString_FromString(self->seq->strip->proxy ? self->seq->strip->proxy->dir : "");
|
|
}
|
|
|
|
static int Sequence_setProxyDir(BPy_Sequence * self, PyObject * value)
|
|
{
|
|
char *name = NULL;
|
|
|
|
name = PyString_AsString(value);
|
|
if (!name)
|
|
{
|
|
return EXPP_ReturnIntError(PyExc_TypeError,
|
|
"expected string argument");
|
|
}
|
|
|
|
if (strlen(name) == 0)
|
|
{
|
|
if (self->seq->strip->proxy)
|
|
{
|
|
MEM_freeN(self->seq->strip->proxy);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
self->seq->strip->proxy = MEM_callocN(sizeof (struct StripProxy), "StripProxy");
|
|
strncpy(self->seq->strip->proxy->dir, name, 160);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static PyObject *Sequence_rebuildProxy(BPy_Sequence * self)
|
|
{
|
|
if (self->seq->strip->proxy)
|
|
seq_proxy_rebuild(self->seq);
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
static PyObject *Sequence_getSound(BPy_Sequence * self)
|
|
{
|
|
if (self->seq->type == SEQ_RAM_SOUND && self->seq->sound)
|
|
return Sound_CreatePyObject(self->seq->sound);
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
static PyObject *Sequence_getIpo(BPy_Sequence * self)
|
|
{
|
|
struct Ipo *ipo;
|
|
|
|
ipo = self->seq->ipo;
|
|
|
|
if (ipo)
|
|
return Ipo_CreatePyObject(ipo);
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
static PyObject *SceneSeq_getActive(BPy_SceneSeq * self)
|
|
{
|
|
Sequence *last_seq = NULL, *seq;
|
|
Editing *ed = self->scene->ed;
|
|
|
|
if (!ed)
|
|
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
|
|
"scene has no sequence data to edit");
|
|
|
|
seq = ed->seqbasep->first;
|
|
|
|
while (seq)
|
|
{
|
|
if (seq->flag & SELECT)
|
|
last_seq = seq;
|
|
|
|
seq = seq->next;
|
|
}
|
|
if (last_seq)
|
|
return Sequence_CreatePyObject(last_seq, NULL, self->scene);
|
|
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
static PyObject *SceneSeq_getMetaStrip(BPy_SceneSeq * self)
|
|
{
|
|
Sequence *seq = NULL;
|
|
Editing *ed = self->scene->ed;
|
|
MetaStack *ms;
|
|
if (!ed)
|
|
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
|
|
"scene has no sequence data to edit");
|
|
|
|
ms = ed->metastack.last;
|
|
if (!ms)
|
|
Py_RETURN_NONE;
|
|
|
|
seq = ms->parseq;
|
|
return Sequence_CreatePyObject(seq, NULL, self->scene);
|
|
}
|
|
|
|
/*
|
|
* this should accept a Py_None argument and just delete the Ipo link
|
|
* (as Object_clearIpo() does)
|
|
*/
|
|
|
|
static int Sequence_setIpo(BPy_Sequence * self, PyObject * value)
|
|
{
|
|
Ipo *ipo = NULL;
|
|
Ipo *oldipo;
|
|
ID *id;
|
|
|
|
oldipo = self->seq->ipo;
|
|
|
|
/* if parameter is not None, check for valid Ipo */
|
|
|
|
if (value != Py_None)
|
|
{
|
|
if (!BPy_Ipo_Check(value))
|
|
return EXPP_ReturnIntError(PyExc_TypeError,
|
|
"expected an Ipo object");
|
|
|
|
ipo = Ipo_FromPyObject(value);
|
|
|
|
if (!ipo)
|
|
return EXPP_ReturnIntError(PyExc_RuntimeError,
|
|
"null ipo!");
|
|
|
|
if (ipo->blocktype != ID_SEQ)
|
|
return EXPP_ReturnIntError(PyExc_TypeError,
|
|
"Ipo is not a sequence data Ipo");
|
|
}
|
|
|
|
/* if already linked to Ipo, delete link */
|
|
|
|
if (oldipo)
|
|
{
|
|
id = &oldipo->id;
|
|
if (id->us > 0)
|
|
id->us--;
|
|
}
|
|
|
|
/* assign new Ipo and increment user count, or set to NULL if deleting */
|
|
|
|
self->seq->ipo = ipo;
|
|
if (ipo)
|
|
id_us_plus(&ipo->id);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static PyObject *Sequence_getScene(BPy_Sequence * self)
|
|
{
|
|
struct Scene *scene;
|
|
|
|
scene = self->seq->scene;
|
|
|
|
if (scene)
|
|
return Scene_CreatePyObject(scene);
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
static PyObject *Sequence_getImages(BPy_Sequence * self)
|
|
{
|
|
Strip *strip;
|
|
StripElem *se;
|
|
int i;
|
|
PyObject *list, *ret;
|
|
|
|
if (self->seq->type != SEQ_IMAGE)
|
|
{
|
|
list = PyList_New(0);
|
|
ret = Py_BuildValue("sO", "", list);
|
|
Py_DECREF(list);
|
|
return ret;
|
|
}
|
|
|
|
/*return EXPP_ReturnPyObjError( PyExc_TypeError,
|
|
"Sequence is not an image type" );*/
|
|
|
|
|
|
strip = self->seq->strip;
|
|
se = strip->stripdata;
|
|
list = PyList_New(strip->len);
|
|
|
|
for (i = 0; i < strip->len; i++, se++)
|
|
{
|
|
PyList_SetItem(list, i, PyString_FromString(se->name));
|
|
}
|
|
|
|
ret = Py_BuildValue("sO", strip->dir, list);
|
|
Py_DECREF(list);
|
|
return ret;
|
|
}
|
|
|
|
static int Sequence_setImages(BPy_Sequence * self, PyObject *value)
|
|
{
|
|
Strip *strip;
|
|
StripElem *se;
|
|
int i;
|
|
PyObject *list;
|
|
char *basepath, *name;
|
|
|
|
if (self->seq->type != SEQ_IMAGE)
|
|
{
|
|
return EXPP_ReturnIntError(PyExc_TypeError,
|
|
"Sequence is not an image type");
|
|
}
|
|
|
|
if (!PyArg_ParseTuple
|
|
(value, "sO!", &basepath, &PyList_Type, &list))
|
|
return EXPP_ReturnIntError(PyExc_TypeError,
|
|
"expected string and optional list argument");
|
|
|
|
strip = self->seq->strip;
|
|
se = strip->stripdata;
|
|
|
|
/* for now dont support different image list sizes */
|
|
if (PyList_Size(list) != strip->len)
|
|
{
|
|
return EXPP_ReturnIntError(PyExc_TypeError,
|
|
"at the moment only image lista with the same number of images as the strip are supported");
|
|
}
|
|
|
|
strncpy(strip->dir, basepath, sizeof (strip->dir));
|
|
|
|
for (i = 0; i < strip->len; i++, se++)
|
|
{
|
|
name = PyString_AsString(PyList_GetItem(list, i));
|
|
if (name)
|
|
{
|
|
strncpy(se->name, name, sizeof (se->name));
|
|
}
|
|
else
|
|
{
|
|
PyErr_Clear();
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static PyObject *M_Sequence_BlendModesDict(void)
|
|
{
|
|
PyObject *M = PyConstant_New();
|
|
|
|
if (M)
|
|
{
|
|
BPy_constant *d = (BPy_constant *) M;
|
|
PyConstant_Insert(d, "CROSS", PyInt_FromLong(SEQ_CROSS));
|
|
PyConstant_Insert(d, "ADD", PyInt_FromLong(SEQ_ADD));
|
|
PyConstant_Insert(d, "SUBTRACT", PyInt_FromLong(SEQ_SUB));
|
|
PyConstant_Insert(d, "ALPHAOVER", PyInt_FromLong(SEQ_ALPHAOVER));
|
|
PyConstant_Insert(d, "ALPHAUNDER", PyInt_FromLong(SEQ_ALPHAUNDER));
|
|
PyConstant_Insert(d, "GAMMACROSS", PyInt_FromLong(SEQ_GAMCROSS));
|
|
PyConstant_Insert(d, "MULTIPLY", PyInt_FromLong(SEQ_MUL));
|
|
PyConstant_Insert(d, "OVERDROP", PyInt_FromLong(SEQ_OVERDROP));
|
|
PyConstant_Insert(d, "PLUGIN", PyInt_FromLong(SEQ_PLUGIN));
|
|
PyConstant_Insert(d, "WIPE", PyInt_FromLong(SEQ_WIPE));
|
|
PyConstant_Insert(d, "GLOW", PyInt_FromLong(SEQ_GLOW));
|
|
PyConstant_Insert(d, "TRANSFORM", PyInt_FromLong(SEQ_TRANSFORM));
|
|
PyConstant_Insert(d, "COLOR", PyInt_FromLong(SEQ_COLOR));
|
|
PyConstant_Insert(d, "SPEED", PyInt_FromLong(SEQ_SPEED));
|
|
}
|
|
return M;
|
|
}
|
|
|
|
static PyObject *Sequence_getBlendMode(BPy_Sequence * self)
|
|
{
|
|
return PyInt_FromLong(self->seq->blend_mode);
|
|
}
|
|
|
|
static int Sequence_setBlendMode(BPy_Sequence * self, PyObject * value)
|
|
{
|
|
struct Sequence *seq = self->seq;
|
|
int number = PyInt_AsLong(value);
|
|
|
|
if (number == -1 && PyErr_Occurred())
|
|
return EXPP_ReturnIntError(PyExc_TypeError, "expected an int value");
|
|
|
|
if (!seq_can_blend(seq))
|
|
return EXPP_ReturnIntError(PyExc_AttributeError, "this sequence type dosnt support blending");
|
|
|
|
if (number < SEQ_EFFECT || number > SEQ_EFFECT_MAX)
|
|
return EXPP_ReturnIntError(PyExc_TypeError, "expected an int value");
|
|
|
|
seq->blend_mode = number;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* get floating point attributes
|
|
*/
|
|
static PyObject *getIntAttr(BPy_Sequence *self, void *type)
|
|
{
|
|
int param;
|
|
struct Sequence *seq = self->seq;
|
|
|
|
/*printf("%i %i %i %i %i %i %i %i %i\n", seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->startdisp, seq->enddisp, seq->depth );*/
|
|
switch (GET_INT_FROM_POINTER(type))
|
|
{
|
|
case EXPP_SEQ_ATTR_TYPE:
|
|
param = seq->type;
|
|
break;
|
|
case EXPP_SEQ_ATTR_CHAN:
|
|
param = seq->machine;
|
|
break;
|
|
case EXPP_SEQ_ATTR_LENGTH:
|
|
param = seq->len;
|
|
break;
|
|
case EXPP_SEQ_ATTR_START:
|
|
param = seq->start;
|
|
break;
|
|
case EXPP_SEQ_ATTR_STARTOFS:
|
|
param = seq->startofs;
|
|
break;
|
|
case EXPP_SEQ_ATTR_ENDOFS:
|
|
param = seq->endofs;
|
|
break;
|
|
case EXPP_SEQ_ATTR_STARTSTILL:
|
|
param = seq->startstill;
|
|
break;
|
|
case EXPP_SEQ_ATTR_ENDSTILL:
|
|
param = seq->endstill;
|
|
break;
|
|
case EXPP_SEQ_ATTR_STARTDISP:
|
|
param = seq->startdisp;
|
|
break;
|
|
case EXPP_SEQ_ATTR_ENDDISP:
|
|
param = seq->enddisp;
|
|
break;
|
|
default:
|
|
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
|
|
"undefined type in getIntAttr");
|
|
}
|
|
|
|
return PyInt_FromLong(param);
|
|
}
|
|
|
|
/* internal functions for recursivly updating metastrip locatons */
|
|
static void intern_pos_update(Sequence * seq)
|
|
{
|
|
/* update startdisp and enddisp */
|
|
calc_sequence_disp(seq);
|
|
}
|
|
|
|
void intern_recursive_pos_update(Sequence * seq, int offset)
|
|
{
|
|
Sequence *iterseq;
|
|
intern_pos_update(seq);
|
|
if (seq->type != SEQ_META) return;
|
|
|
|
for (iterseq = seq->seqbase.first; iterseq; iterseq = iterseq->next)
|
|
{
|
|
iterseq->start -= offset;
|
|
intern_recursive_pos_update(iterseq, offset);
|
|
}
|
|
}
|
|
|
|
static int setIntAttrClamp(BPy_Sequence *self, PyObject *value, void *type)
|
|
{
|
|
struct Sequence *seq = self->seq;
|
|
int number, origval = 0, regen_data;
|
|
|
|
if (!PyInt_Check(value))
|
|
return EXPP_ReturnIntError(PyExc_TypeError, "expected an int value");
|
|
|
|
number = PyInt_AS_LONG(value);
|
|
|
|
switch (GET_INT_FROM_POINTER(type))
|
|
{
|
|
case EXPP_SEQ_ATTR_CHAN:
|
|
CLAMP(number, 1, 1024);
|
|
seq->machine = number;
|
|
regen_data = 0;
|
|
break;
|
|
case EXPP_SEQ_ATTR_START:
|
|
if (self->seq->type == SEQ_EFFECT)
|
|
return EXPP_ReturnIntError(PyExc_RuntimeError,
|
|
"cannot set the location of an effect directly");
|
|
CLAMP(number, -MAXFRAME, MAXFRAME);
|
|
origval = seq->start;
|
|
seq->start = number;
|
|
regen_data = 0;
|
|
break;
|
|
|
|
case EXPP_SEQ_ATTR_STARTOFS:
|
|
if (self->seq->type == SEQ_EFFECT)
|
|
return EXPP_ReturnIntError(PyExc_RuntimeError,
|
|
"This property dosnt apply to an effect");
|
|
CLAMP(number, 0, seq->len - seq->endofs);
|
|
origval = seq->startofs;
|
|
seq->startofs = number;
|
|
regen_data = 1;
|
|
break;
|
|
case EXPP_SEQ_ATTR_ENDOFS:
|
|
if (self->seq->type == SEQ_EFFECT)
|
|
return EXPP_ReturnIntError(PyExc_RuntimeError,
|
|
"This property dosnt apply to an effect");
|
|
CLAMP(number, 0, seq->len - seq->startofs);
|
|
origval = seq->endofs;
|
|
seq->endofs = number;
|
|
regen_data = 1;
|
|
break;
|
|
case EXPP_SEQ_ATTR_STARTSTILL:
|
|
if (self->seq->type == SEQ_EFFECT)
|
|
return EXPP_ReturnIntError(PyExc_RuntimeError,
|
|
"This property dosnt apply to an effect");
|
|
CLAMP(number, 1, MAXFRAME);
|
|
origval = seq->startstill;
|
|
seq->startstill = number;
|
|
regen_data = 1;
|
|
break;
|
|
case EXPP_SEQ_ATTR_ENDSTILL:
|
|
if (self->seq->type == SEQ_EFFECT)
|
|
return EXPP_ReturnIntError(PyExc_RuntimeError,
|
|
"This property dosnt apply to an effect");
|
|
CLAMP(number, seq->startstill + 1, MAXFRAME);
|
|
origval = seq->endstill;
|
|
seq->endstill = number;
|
|
regen_data = 1;
|
|
break;
|
|
case EXPP_SEQ_ATTR_LENGTH:
|
|
if (self->seq->type == SEQ_EFFECT)
|
|
return EXPP_ReturnIntError(PyExc_RuntimeError,
|
|
"cannot set the length of an effect directly");
|
|
CLAMP(number, 1, MAXFRAME);
|
|
origval = seq->len;
|
|
seq->len = number;
|
|
regen_data = 1;
|
|
break;
|
|
default:
|
|
return EXPP_ReturnIntError(PyExc_RuntimeError,
|
|
"undefined type in setFloatAttrClamp");
|
|
}
|
|
|
|
if (number != origval)
|
|
{
|
|
intern_pos_update(seq);
|
|
|
|
if (GET_INT_FROM_POINTER(type) == EXPP_SEQ_ATTR_START)
|
|
intern_recursive_pos_update(seq, origval - seq->start);
|
|
|
|
if (regen_data)
|
|
{
|
|
new_tstripdata(seq);
|
|
}
|
|
|
|
calc_sequence(seq);
|
|
calc_sequence_disp(seq);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static PyObject *getFlagAttr(BPy_Sequence *self, void *type)
|
|
{
|
|
if (self->seq->flag & GET_INT_FROM_POINTER(type))
|
|
Py_RETURN_TRUE;
|
|
else
|
|
Py_RETURN_FALSE;
|
|
}
|
|
|
|
/*
|
|
* set floating point attributes which require clamping
|
|
*/
|
|
|
|
static int setFlagAttr(BPy_Sequence *self, PyObject *value, void *type)
|
|
{
|
|
int t = GET_INT_FROM_POINTER(type);
|
|
int param = PyObject_IsTrue(value);
|
|
|
|
if (param == -1)
|
|
return EXPP_ReturnIntError(PyExc_TypeError,
|
|
"expected True/False or 0/1");
|
|
|
|
if (param)
|
|
self->seq->flag |= t;
|
|
else
|
|
{
|
|
/* dont allow leftsel and rightsel when its not selected */
|
|
if (t == SELECT)
|
|
t = t + SEQ_LEFTSEL + SEQ_RIGHTSEL;
|
|
|
|
self->seq->flag &= ~t;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static PyObject *getEffectSeq(BPy_Sequence *self, void *type)
|
|
{
|
|
int t = GET_INT_FROM_POINTER(type);
|
|
Sequence *seq = NULL;
|
|
switch (t)
|
|
{
|
|
case 1:
|
|
seq = self->seq->seq1;
|
|
break;
|
|
case 2:
|
|
seq = self->seq->seq2;
|
|
break;
|
|
case 3:
|
|
seq = self->seq->seq3;
|
|
break;
|
|
}
|
|
|
|
if (seq)
|
|
{
|
|
return Sequence_CreatePyObject(seq, NULL, self->scene);
|
|
}
|
|
else
|
|
{
|
|
Py_RETURN_NONE;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* set one of the effect sequences
|
|
*/
|
|
|
|
static int setEffectSeq(BPy_Sequence *self, PyObject *value, void *type)
|
|
{
|
|
int t = GET_INT_FROM_POINTER(type);
|
|
Sequence **seq;
|
|
if ((value == Py_None || BPy_Sequence_Check(value)) == 0)
|
|
return EXPP_ReturnIntError(PyExc_TypeError,
|
|
"expected Sequence or None");
|
|
|
|
switch (t)
|
|
{
|
|
case 1:
|
|
seq = &self->seq->seq1;
|
|
break;
|
|
case 2:
|
|
seq = &self->seq->seq2;
|
|
break;
|
|
case 3:
|
|
seq = &self->seq->seq3;
|
|
break;
|
|
}
|
|
|
|
if (value == Py_None)
|
|
*seq = NULL;
|
|
else
|
|
{
|
|
Sequence *newseq = ((BPy_Sequence *) value)->seq;
|
|
if (newseq == self->seq)
|
|
{
|
|
return EXPP_ReturnIntError(PyExc_TypeError, "cannot set a sequence as its own effect");
|
|
}
|
|
|
|
*seq = ((BPy_Sequence *) value)->seq;
|
|
}
|
|
|
|
|
|
calc_sequence(self->seq);
|
|
update_changed_seq_and_deps(self->seq, 1, 1);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
static PyObject *getSpeedEffect(BPy_Sequence *self, PyObject *value, void *type)
|
|
{
|
|
int t = GET_INT_FROM_POINTER(type);
|
|
Sequence *seq= self->seq;
|
|
SpeedControlVars * v;
|
|
|
|
if (seq->type != SEQ_SPEED)
|
|
return EXPP_ReturnPyObjError(PyExc_TypeError, "Not a speed effect strip" );
|
|
|
|
v = (SpeedControlVars *)seq->effectdata;
|
|
|
|
switch (t) {
|
|
case EXPP_SEQ_ATTR_EFFECT_GLOBAL_SPEED:
|
|
return PyFloat_FromDouble(v->globalSpeed);
|
|
break;
|
|
case EXPP_SEQ_ATTR_EFFECT_IPO_IS_VELOCITY:
|
|
return PyBool_FromLong(v->flags & SEQ_SPEED_INTEGRATE);
|
|
break;
|
|
case EXPP_SEQ_ATTR_EFFECT_FRAME_BLENDING:
|
|
return PyBool_FromLong(v->flags & SEQ_SPEED_BLEND);
|
|
break;
|
|
case EXPP_SEQ_ATTR_EFFECT_NORMALIZE_IPO_0_1:
|
|
return PyBool_FromLong(v->flags & SEQ_SPEED_COMPRESS_IPO_Y);
|
|
break;
|
|
}
|
|
|
|
if (PyErr_Occurred()) {
|
|
return NULL;
|
|
}
|
|
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
/*
|
|
* set one of the effect sequences
|
|
*/
|
|
|
|
static int setSpeedEffect(BPy_Sequence *self, PyObject *value, void *type)
|
|
{
|
|
int t = GET_INT_FROM_POINTER(type);
|
|
Sequence *seq= self->seq;
|
|
SpeedControlVars * v;
|
|
|
|
if (seq->type != SEQ_SPEED)
|
|
return EXPP_ReturnIntError(PyExc_TypeError, "Not a speed effect strip" );
|
|
|
|
v = (SpeedControlVars *)seq->effectdata;
|
|
|
|
switch (t) {
|
|
case EXPP_SEQ_ATTR_EFFECT_GLOBAL_SPEED:
|
|
v->globalSpeed= PyFloat_AsDouble(value);
|
|
CLAMP(v->globalSpeed, 0.0f, 100.0f);
|
|
break;
|
|
case EXPP_SEQ_ATTR_EFFECT_IPO_IS_VELOCITY:
|
|
if (PyObject_IsTrue( value )) v->flags |= SEQ_SPEED_INTEGRATE;
|
|
else v->flags &= ~SEQ_SPEED_INTEGRATE;
|
|
break;
|
|
case EXPP_SEQ_ATTR_EFFECT_FRAME_BLENDING:
|
|
if (PyObject_IsTrue( value )) v->flags |= SEQ_SPEED_BLEND;
|
|
else v->flags &= ~SEQ_SPEED_BLEND;
|
|
break;
|
|
case EXPP_SEQ_ATTR_EFFECT_NORMALIZE_IPO_0_1:
|
|
if (PyObject_IsTrue( value )) v->flags |= SEQ_SPEED_COMPRESS_IPO_Y;
|
|
else v->flags &= ~SEQ_SPEED_COMPRESS_IPO_Y;
|
|
break;
|
|
}
|
|
|
|
if (PyErr_Occurred()) {
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
static PyObject *getWipeEffect(BPy_Sequence *self, PyObject *value, void *type)
|
|
{
|
|
int t = GET_INT_FROM_POINTER(type);
|
|
Sequence *seq= self->seq;
|
|
WipeVars * v;
|
|
|
|
if (seq->type != SEQ_WIPE)
|
|
return EXPP_ReturnPyObjError(PyExc_TypeError, "Not a wipe effect strip" );
|
|
|
|
v = (WipeVars *)seq->effectdata;
|
|
|
|
switch (t) {
|
|
case EXPP_SEQ_ATTR_EFFECT_ANGLE:
|
|
return PyFloat_FromDouble(v->angle);
|
|
break;
|
|
case EXPP_SEQ_ATTR_EFFECT_BLUR:
|
|
return PyFloat_FromDouble(v->edgeWidth);
|
|
break;
|
|
case EXPP_SEQ_ATTR_EFFECT_WIPE_IN:
|
|
return PyBool_FromLong(v->forward);
|
|
break;
|
|
}
|
|
|
|
if (PyErr_Occurred()) {
|
|
return NULL;
|
|
}
|
|
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
/*
|
|
* set one of the effect sequences
|
|
*/
|
|
|
|
static int setWipeEffect(BPy_Sequence *self, PyObject *value, void *type)
|
|
{
|
|
int t = GET_INT_FROM_POINTER(type);
|
|
Sequence *seq= self->seq;
|
|
WipeVars * v;
|
|
|
|
if (seq->type != SEQ_WIPE)
|
|
return EXPP_ReturnIntError(PyExc_TypeError, "Not a wipe effect strip" );
|
|
|
|
v = (WipeVars *)seq->effectdata;
|
|
|
|
switch (t) {
|
|
case EXPP_SEQ_ATTR_EFFECT_ANGLE:
|
|
v->angle= PyFloat_AsDouble(value);
|
|
CLAMP(v->angle, -90.0f, 90.0f);
|
|
break;
|
|
case EXPP_SEQ_ATTR_EFFECT_BLUR:
|
|
v->edgeWidth= PyFloat_AsDouble(value);
|
|
CLAMP(v->edgeWidth, -90.0f, 90.0f);
|
|
break;
|
|
case EXPP_SEQ_ATTR_EFFECT_WIPE_IN:
|
|
if (PyObject_IsTrue( value )) v->forward= 1;
|
|
else v->forward= 0;
|
|
break;
|
|
}
|
|
|
|
if (PyErr_Occurred()) {
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Python attributes get/set structure: */
|
|
/*****************************************************************************/
|
|
static PyGetSetDef BPy_Sequence_getseters[] = {
|
|
{"name",
|
|
(getter) Sequence_getName, (setter) Sequence_setName,
|
|
"Sequence name",
|
|
NULL},
|
|
{"proxyDir",
|
|
(getter) Sequence_getProxyDir, (setter) Sequence_setProxyDir,
|
|
"Sequence proxy directory",
|
|
NULL},
|
|
{"ipo",
|
|
(getter) Sequence_getIpo, (setter) Sequence_setIpo,
|
|
"Sequence ipo",
|
|
NULL},
|
|
|
|
{"scene",
|
|
(getter) Sequence_getScene, (setter) NULL,
|
|
"Sequence scene",
|
|
NULL},
|
|
{"sound",
|
|
(getter) Sequence_getSound, (setter) NULL,
|
|
"Sequence name",
|
|
NULL},
|
|
{"images",
|
|
(getter) Sequence_getImages, (setter) Sequence_setImages,
|
|
"Sequence scene",
|
|
NULL},
|
|
{"blendMode",
|
|
(getter) Sequence_getBlendMode, (setter) Sequence_setBlendMode,
|
|
"Sequence Blend Mode",
|
|
NULL},
|
|
|
|
{"type",
|
|
(getter) getIntAttr, (setter) NULL,
|
|
"",
|
|
(void *) EXPP_SEQ_ATTR_TYPE},
|
|
{"channel",
|
|
(getter) getIntAttr, (setter) setIntAttrClamp,
|
|
"",
|
|
(void *) EXPP_SEQ_ATTR_CHAN},
|
|
|
|
{"length",
|
|
(getter) getIntAttr, (setter) setIntAttrClamp,
|
|
"",
|
|
(void *) EXPP_SEQ_ATTR_LENGTH},
|
|
{"start",
|
|
(getter) getIntAttr, (setter) setIntAttrClamp,
|
|
"",
|
|
(void *) EXPP_SEQ_ATTR_START},
|
|
{"startOffset",
|
|
(getter) getIntAttr, (setter) setIntAttrClamp,
|
|
"",
|
|
(void *) EXPP_SEQ_ATTR_STARTOFS},
|
|
{"endOffset",
|
|
(getter) getIntAttr, (setter) setIntAttrClamp,
|
|
"",
|
|
(void *) EXPP_SEQ_ATTR_ENDOFS},
|
|
{"startStill",
|
|
(getter) getIntAttr, (setter) setIntAttrClamp,
|
|
"",
|
|
(void *) EXPP_SEQ_ATTR_STARTSTILL},
|
|
{"endStill",
|
|
(getter) getIntAttr, (setter) setIntAttrClamp,
|
|
"",
|
|
(void *) EXPP_SEQ_ATTR_ENDSTILL},
|
|
{"startDisp",
|
|
(getter) getIntAttr, (setter) NULL,
|
|
"",
|
|
(void *) EXPP_SEQ_ATTR_STARTDISP},
|
|
{"endDisp",
|
|
(getter) getIntAttr, (setter) NULL,
|
|
"",
|
|
(void *) EXPP_SEQ_ATTR_ENDDISP},
|
|
|
|
{"sel",
|
|
(getter) getFlagAttr, (setter) setFlagAttr,
|
|
"Sequence audio mute option",
|
|
(void *) SELECT},
|
|
{"selLeft",
|
|
(getter) getFlagAttr, (setter) setFlagAttr,
|
|
"",
|
|
(void *) SEQ_LEFTSEL},
|
|
{"selRight",
|
|
(getter) getFlagAttr, (setter) setFlagAttr,
|
|
"",
|
|
(void *) SEQ_RIGHTSEL},
|
|
{"filtery",
|
|
(getter) getFlagAttr, (setter) setFlagAttr,
|
|
"",
|
|
(void *) SEQ_FILTERY},
|
|
{"flipX",
|
|
(getter) getFlagAttr, (setter) setFlagAttr,
|
|
"",
|
|
(void *) SEQ_FLIPX},
|
|
{"flipY",
|
|
(getter) getFlagAttr, (setter) setFlagAttr,
|
|
"",
|
|
(void *) SEQ_FLIPY},
|
|
{"mute",
|
|
(getter) getFlagAttr, (setter) setFlagAttr,
|
|
"",
|
|
(void *) SEQ_MUTE},
|
|
{"floatBuffer",
|
|
(getter) getFlagAttr, (setter) setFlagAttr,
|
|
"",
|
|
(void *) SEQ_MAKE_FLOAT},
|
|
{"lock",
|
|
(getter) getFlagAttr, (setter) setFlagAttr,
|
|
"",
|
|
(void *) SEQ_LOCK},
|
|
{"useProxy",
|
|
(getter) getFlagAttr, (setter) setFlagAttr,
|
|
"",
|
|
(void *) SEQ_USE_PROXY},
|
|
{"premul",
|
|
(getter) getFlagAttr, (setter) setFlagAttr,
|
|
"",
|
|
(void *) SEQ_MAKE_PREMUL},
|
|
{"reversed",
|
|
(getter) getFlagAttr, (setter) setFlagAttr,
|
|
"",
|
|
(void *) SEQ_REVERSE_FRAMES},
|
|
{"ipoLocked",
|
|
(getter) getFlagAttr, (setter) setFlagAttr,
|
|
"",
|
|
(void *) SEQ_IPO_FRAME_LOCKED},
|
|
{"seq1",
|
|
(getter) getEffectSeq, (setter) setEffectSeq,
|
|
"",
|
|
(void *) 1},
|
|
{"seq2",
|
|
(getter) getEffectSeq, (setter) setEffectSeq,
|
|
"",
|
|
(void *) 2},
|
|
{"seq3",
|
|
(getter) getEffectSeq, (setter) setEffectSeq,
|
|
"",
|
|
(void *) 3},
|
|
|
|
/* effects */
|
|
{"speedEffectGlobalSpeed",
|
|
(getter) getSpeedEffect, (setter) setSpeedEffect,
|
|
"",
|
|
(void *) EXPP_SEQ_ATTR_EFFECT_GLOBAL_SPEED},
|
|
{"speedEffectIpoVelocity",
|
|
(getter) getSpeedEffect, (setter) setSpeedEffect,
|
|
"",
|
|
(void *) EXPP_SEQ_ATTR_EFFECT_IPO_IS_VELOCITY},
|
|
{"speedEffectFrameBlending",
|
|
(getter) getSpeedEffect, (setter) setSpeedEffect,
|
|
"",
|
|
(void *) EXPP_SEQ_ATTR_EFFECT_FRAME_BLENDING},
|
|
{"speedEffectIpoNormalize",
|
|
(getter) getSpeedEffect, (setter) setSpeedEffect,
|
|
"",
|
|
(void *) EXPP_SEQ_ATTR_EFFECT_NORMALIZE_IPO_0_1},
|
|
|
|
{"wipeEffectAngle",
|
|
(getter) getWipeEffect, (setter) setWipeEffect,
|
|
"",
|
|
(void *) EXPP_SEQ_ATTR_EFFECT_ANGLE},
|
|
{"wipeEffectBlur",
|
|
(getter) getWipeEffect, (setter) setWipeEffect,
|
|
"",
|
|
(void *) EXPP_SEQ_ATTR_EFFECT_BLUR},
|
|
{"wipeEffectWipeIn",
|
|
(getter) getWipeEffect, (setter) setWipeEffect,
|
|
"",
|
|
(void *) EXPP_SEQ_ATTR_EFFECT_WIPE_IN},
|
|
|
|
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
|
|
};
|
|
|
|
/*****************************************************************************/
|
|
/* Python attributes get/set structure: */
|
|
/*****************************************************************************/
|
|
static PyGetSetDef BPy_SceneSeq_getseters[] = {
|
|
{"active",
|
|
(getter) SceneSeq_getActive, (setter) NULL,
|
|
"the active strip",
|
|
NULL},
|
|
{"metastrip",
|
|
(getter) SceneSeq_getMetaStrip, (setter) NULL,
|
|
"The currently active metastrip the user is editing",
|
|
NULL},
|
|
{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
|
|
};
|
|
|
|
/*****************************************************************************/
|
|
/* Python TypeSequence structure definition: */
|
|
/*****************************************************************************/
|
|
PyTypeObject Sequence_Type = {
|
|
PyObject_HEAD_INIT(NULL) /* required py macro */
|
|
0, /* ob_size */
|
|
/* For printing, in format "<module>.<name>" */
|
|
"Blender Sequence", /* char *tp_name; */
|
|
sizeof ( BPy_Sequence), /* int tp_basicsize; */
|
|
0, /* tp_itemsize; For allocation */
|
|
|
|
/* Methods to implement standard operations */
|
|
|
|
NULL, /* destructor tp_dealloc; */
|
|
NULL, /* printfunc tp_print; */
|
|
NULL, /* getattrfunc tp_getattr; */
|
|
NULL, /* setattrfunc tp_setattr; */
|
|
(cmpfunc) Sequence_compare, /* cmpfunc tp_compare; */
|
|
(reprfunc) Sequence_repr, /* reprfunc tp_repr; */
|
|
|
|
/* Method suites for standard classes */
|
|
|
|
NULL, /* PyNumberMethods *tp_as_number; */
|
|
NULL, /* PySequenceMethods *tp_as_sequence; */
|
|
NULL, /* PyMappingMethods *tp_as_mapping; */
|
|
|
|
/* More standard operations (here for binary compatibility) */
|
|
|
|
NULL, /* hashfunc tp_hash; */
|
|
NULL, /* ternaryfunc tp_call; */
|
|
NULL, /* reprfunc tp_str; */
|
|
NULL, /* getattrofunc tp_getattro; */
|
|
NULL, /* setattrofunc tp_setattro; */
|
|
|
|
/* Functions to access object as input/output buffer */
|
|
NULL, /* PyBufferProcs *tp_as_buffer; */
|
|
|
|
/*** Flags to define presence of optional/expanded features ***/
|
|
Py_TPFLAGS_DEFAULT, /* long tp_flags; */
|
|
|
|
NULL, /* char *tp_doc; Documentation string */
|
|
/*** Assigned meaning in release 2.0 ***/
|
|
/* call function for all accessible objects */
|
|
NULL, /* traverseproc tp_traverse; */
|
|
|
|
/* delete references to contained objects */
|
|
NULL, /* inquiry tp_clear; */
|
|
|
|
/*** Assigned meaning in release 2.1 ***/
|
|
/*** rich comparisons ***/
|
|
NULL, /* richcmpfunc tp_richcompare; */
|
|
|
|
/*** weak reference enabler ***/
|
|
0, /* long tp_weaklistoffset; */
|
|
|
|
/*** Added in release 2.2 ***/
|
|
/* Iterators */
|
|
(getiterfunc) Sequence_getIter, /* getiterfunc tp_iter; */
|
|
(iternextfunc) Sequence_nextIter, /* iternextfunc tp_iternext; */
|
|
|
|
/*** Attribute descriptor and subclassing stuff ***/
|
|
BPy_Sequence_methods, /* struct PyMethodDef *tp_methods; */
|
|
NULL, /* struct PyMemberDef *tp_members; */
|
|
BPy_Sequence_getseters, /* struct PyGetSetDef *tp_getset; */
|
|
NULL, /* struct _typeobject *tp_base; */
|
|
NULL, /* PyObject *tp_dict; */
|
|
NULL, /* descrgetfunc tp_descr_get; */
|
|
NULL, /* descrsetfunc tp_descr_set; */
|
|
0, /* long tp_dictoffset; */
|
|
NULL, /* initproc tp_init; */
|
|
NULL, /* allocfunc tp_alloc; */
|
|
NULL, /* newfunc tp_new; */
|
|
/* Low-level free-memory routine */
|
|
NULL, /* freefunc tp_free; */
|
|
/* For PyObject_IS_GC */
|
|
NULL, /* inquiry tp_is_gc; */
|
|
NULL, /* PyObject *tp_bases; */
|
|
/* method resolution order */
|
|
NULL, /* PyObject *tp_mro; */
|
|
NULL, /* PyObject *tp_cache; */
|
|
NULL, /* PyObject *tp_subclasses; */
|
|
NULL, /* PyObject *tp_weaklist; */
|
|
NULL
|
|
};
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Python TypeSequence structure definition: */
|
|
/*****************************************************************************/
|
|
PyTypeObject SceneSeq_Type = {
|
|
PyObject_HEAD_INIT(NULL) /* required py macro */
|
|
0, /* ob_size */
|
|
/* For printing, in format "<module>.<name>" */
|
|
"Blender SceneSeq", /* char *tp_name; */
|
|
sizeof ( BPy_Sequence), /* int tp_basicsize; */
|
|
0, /* tp_itemsize; For allocation */
|
|
|
|
/* Methods to implement standard operations */
|
|
|
|
NULL, /* destructor tp_dealloc; */
|
|
NULL, /* printfunc tp_print; */
|
|
NULL, /* getattrfunc tp_getattr; */
|
|
NULL, /* setattrfunc tp_setattr; */
|
|
(cmpfunc) SceneSeq_compare, /* cmpfunc tp_compare; */
|
|
(reprfunc) SceneSeq_repr, /* reprfunc tp_repr; */
|
|
|
|
/* Method suites for standard classes */
|
|
|
|
NULL, /* PyNumberMethods *tp_as_number; */
|
|
NULL, /* PySequenceMethods *tp_as_sequence; */
|
|
NULL, /* PyMappingMethods *tp_as_mapping; */
|
|
|
|
/* More standard operations (here for binary compatibility) */
|
|
|
|
NULL, /* hashfunc tp_hash; */
|
|
NULL, /* ternaryfunc tp_call; */
|
|
NULL, /* reprfunc tp_str; */
|
|
NULL, /* getattrofunc tp_getattro; */
|
|
NULL, /* setattrofunc tp_setattro; */
|
|
|
|
/* Functions to access object as input/output buffer */
|
|
NULL, /* PyBufferProcs *tp_as_buffer; */
|
|
|
|
/*** Flags to define presence of optional/expanded features ***/
|
|
Py_TPFLAGS_DEFAULT, /* long tp_flags; */
|
|
|
|
NULL, /* char *tp_doc; Documentation string */
|
|
/*** Assigned meaning in release 2.0 ***/
|
|
/* call function for all accessible objects */
|
|
NULL, /* traverseproc tp_traverse; */
|
|
|
|
/* delete references to contained objects */
|
|
NULL, /* inquiry tp_clear; */
|
|
|
|
/*** Assigned meaning in release 2.1 ***/
|
|
/*** rich comparisons ***/
|
|
NULL, /* richcmpfunc tp_richcompare; */
|
|
|
|
/*** weak reference enabler ***/
|
|
0, /* long tp_weaklistoffset; */
|
|
|
|
/*** Added in release 2.2 ***/
|
|
/* Iterators */
|
|
(getiterfunc) SceneSeq_getIter, /* getiterfunc tp_iter; */
|
|
(iternextfunc) SceneSeq_nextIter, /* iternextfunc tp_iternext; */
|
|
|
|
/*** Attribute descriptor and subclassing stuff ***/
|
|
BPy_SceneSeq_methods, /* struct PyMethodDef *tp_methods; */
|
|
NULL, /* struct PyMemberDef *tp_members; */
|
|
BPy_SceneSeq_getseters, /* struct PyGetSetDef *tp_getset; */
|
|
NULL, /* struct _typeobject *tp_base; */
|
|
NULL, /* PyObject *tp_dict; */
|
|
NULL, /* descrgetfunc tp_descr_get; */
|
|
NULL, /* descrsetfunc tp_descr_set; */
|
|
0, /* long tp_dictoffset; */
|
|
NULL, /* initproc tp_init; */
|
|
NULL, /* allocfunc tp_alloc; */
|
|
NULL, /* newfunc tp_new; */
|
|
/* Low-level free-memory routine */
|
|
NULL, /* freefunc tp_free; */
|
|
/* For PyObject_IS_GC */
|
|
NULL, /* inquiry tp_is_gc; */
|
|
NULL, /* PyObject *tp_bases; */
|
|
/* method resolution order */
|
|
NULL, /* PyObject *tp_mro; */
|
|
NULL, /* PyObject *tp_cache; */
|
|
NULL, /* PyObject *tp_subclasses; */
|
|
NULL, /* PyObject *tp_weaklist; */
|
|
NULL
|
|
};
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Function: M_Sequence_Get */
|
|
/* Python equivalent: Blender.Sequence.Get */
|
|
/*****************************************************************************/
|
|
/*
|
|
PyObject *M_Sequence_Get( PyObject * self, PyObject * args )
|
|
{
|
|
return SceneSeq_CreatePyObject( G.scene, NULL );
|
|
}
|
|
*/
|
|
|
|
/*****************************************************************************/
|
|
/* Function: initObject */
|
|
|
|
/*****************************************************************************/
|
|
PyObject *Sequence_Init(void)
|
|
{
|
|
PyObject *BlendModesDict = M_Sequence_BlendModesDict();
|
|
PyObject *submodule;
|
|
if (PyType_Ready(&Sequence_Type) < 0)
|
|
return NULL;
|
|
if (PyType_Ready(&SceneSeq_Type) < 0)
|
|
return NULL;
|
|
|
|
/* NULL was M_Sequence_methods*/
|
|
submodule = Py_InitModule3("Blender.Scene.Sequence", NULL,
|
|
"The Blender Sequence module\n\n\
|
|
This module provides access to **Sequence Data** in Blender.\n");
|
|
|
|
if (BlendModesDict)
|
|
PyModule_AddObject(submodule, "BlendModes", BlendModesDict);
|
|
|
|
/*Add SUBMODULES to the module*/
|
|
/*PyDict_SetItemString(dict, "Constraint", Constraint_Init()); //creates a *new* module*/
|
|
return submodule;
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
/* Function: Sequence_CreatePyObject */
|
|
/* Description: This function will create a new BlenObject from an existing */
|
|
/* Object structure. */
|
|
|
|
/*****************************************************************************/
|
|
PyObject *Sequence_CreatePyObject(struct Sequence * seq, struct Sequence * iter, struct Scene *sce)
|
|
{
|
|
BPy_Sequence *pyseq;
|
|
|
|
if (!seq)
|
|
Py_RETURN_NONE;
|
|
|
|
pyseq =
|
|
(BPy_Sequence *) PyObject_NEW(BPy_Sequence, &Sequence_Type);
|
|
|
|
if (pyseq == NULL)
|
|
{
|
|
return ( NULL);
|
|
}
|
|
pyseq->seq = seq;
|
|
pyseq->iter = iter;
|
|
pyseq->scene = sce;
|
|
|
|
return ( (PyObject *) pyseq);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Function: SceneSeq_CreatePyObject */
|
|
/* Description: This function will create a new BlenObject from an existing */
|
|
/* Object structure. */
|
|
|
|
/*****************************************************************************/
|
|
PyObject *SceneSeq_CreatePyObject(struct Scene * scn, struct Sequence * iter)
|
|
{
|
|
BPy_SceneSeq *pysceseq;
|
|
|
|
if (!scn)
|
|
Py_RETURN_NONE;
|
|
|
|
if (!scn->ed)
|
|
{
|
|
Editing *ed;
|
|
ed = scn->ed = MEM_callocN(sizeof (Editing), "addseq");
|
|
ed->seqbasep = &ed->seqbase;
|
|
}
|
|
|
|
pysceseq =
|
|
(BPy_SceneSeq *) PyObject_NEW(BPy_SceneSeq, &SceneSeq_Type);
|
|
|
|
if (pysceseq == NULL)
|
|
{
|
|
return ( NULL);
|
|
}
|
|
pysceseq->scene = scn;
|
|
pysceseq->iter = iter;
|
|
|
|
return ( (PyObject *) pysceseq);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Function: Sequence_FromPyObject */
|
|
/* Description: This function returns the Blender sequence from the given */
|
|
/* PyObject. */
|
|
|
|
/*****************************************************************************/
|
|
struct Sequence *Sequence_FromPyObject(PyObject * py_seq)
|
|
{
|
|
BPy_Sequence *blen_seq;
|
|
|
|
blen_seq = (BPy_Sequence *) py_seq;
|
|
return ( blen_seq->seq);
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Function: Sequence_compare */
|
|
/* Description: This is a callback function for the BPy_Sequence type. It */
|
|
/* compares two Sequence_Type objects. Only the "==" and "!=" */
|
|
/* comparisons are meaninful. Returns 0 for equality and -1 if */
|
|
/* they don't point to the same Blender Object struct. */
|
|
/* In Python it becomes 1 if they are equal, 0 otherwise. */
|
|
|
|
/*****************************************************************************/
|
|
static int Sequence_compare(BPy_Sequence * a, BPy_Sequence * b)
|
|
{
|
|
Sequence *pa = a->seq, *pb = b->seq;
|
|
return ( pa == pb) ? 0 : -1;
|
|
}
|
|
|
|
static int SceneSeq_compare(BPy_SceneSeq * a, BPy_SceneSeq * b)
|
|
{
|
|
|
|
Scene *pa = a->scene, *pb = b->scene;
|
|
return ( pa == pb) ? 0 : -1;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
/* Function: Sequence_repr / SceneSeq_repr */
|
|
/* Description: This is a callback function for the BPy_Sequence type. It */
|
|
/* builds a meaninful string to represent object objects. */
|
|
|
|
/*****************************************************************************/
|
|
static PyObject *Sequence_repr(BPy_Sequence * self)
|
|
{
|
|
return PyString_FromFormat("[Sequence Strip \"%s\"]",
|
|
self->seq->name + 2);
|
|
}
|
|
|
|
static PyObject *SceneSeq_repr(BPy_SceneSeq * self)
|
|
{
|
|
return PyString_FromFormat("[Scene Sequence \"%s\"]",
|
|
self->scene->id.name + 2);
|
|
}
|
|
|