718 lines
18 KiB
C
718 lines
18 KiB
C
/** Ipo module; access to Ipo datablocks in Blender
|
|
* $Id$
|
|
*
|
|
* ***** BEGIN GPL/BL DUAL 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. The Blender
|
|
* Foundation also sells licenses for use in proprietary software under
|
|
* the Blender License. See http://www.blender.org/BL/ for information
|
|
* about this.
|
|
*
|
|
* 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.
|
|
*
|
|
* The Original Code is: all of this file.
|
|
*
|
|
* Contributor(s): none yet.
|
|
*
|
|
* ***** END GPL/BL DUAL LICENSE BLOCK *****
|
|
*
|
|
*/
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
#include "Python.h"
|
|
#include "BPY_macros.h"
|
|
#include "BPY_tools.h"
|
|
|
|
#include "b_interface.h" // most datatypes
|
|
|
|
#include "opy_datablock.h"
|
|
|
|
#include "DNA_curve_types.h"
|
|
|
|
#include "BSE_editipo.h"
|
|
|
|
/* GLOBALS */
|
|
|
|
/* These should be put into a proper dictionary for quicker retrieval..*/
|
|
|
|
NamedEnum g_OB_ipocodes[] = {
|
|
|
|
{ "LocX", OB_LOC_X },
|
|
{ "LocY", OB_LOC_Y },
|
|
{ "LocZ", OB_LOC_Z },
|
|
{ "dLocX", OB_DLOC_X },
|
|
{ "dLocY", OB_DLOC_Y },
|
|
{ "dLocZ", OB_DLOC_Z },
|
|
{ "RotX", OB_ROT_X },
|
|
{ "RotY", OB_ROT_Y },
|
|
{ "RotZ", OB_ROT_Z },
|
|
{ "dRotX", OB_DROT_X },
|
|
{ "dRotY", OB_DROT_Y },
|
|
{ "dRotZ", OB_DROT_Z },
|
|
{ "SizeX", OB_SIZE_X },
|
|
{ "SizeY", OB_SIZE_Y },
|
|
{ "SizeY", OB_SIZE_Z },
|
|
{ "dSizeX", OB_DSIZE_X },
|
|
{ "dSizeY", OB_DSIZE_Y },
|
|
{ "dSizeY", OB_DSIZE_Z },
|
|
{ "Layer", OB_LAY },
|
|
{ "Time", OB_TIME },
|
|
{ 0, 0 }
|
|
};
|
|
|
|
NamedEnum g_MA_ipocodes[] = {
|
|
|
|
{ "R", MA_COL_R },
|
|
{ "G", MA_COL_G },
|
|
{ "B", MA_COL_B },
|
|
{ "Alpha", MA_ALPHA},
|
|
{ "SpecR", MA_SPEC_R },
|
|
{ "SpecG", MA_SPEC_G },
|
|
{ "SpecB", MA_SPEC_B },
|
|
{ "MirR", MA_MIR_R },
|
|
{ "MirG", MA_MIR_G },
|
|
{ "MirB", MA_MIR_B },
|
|
{ "Emit", MA_EMIT },
|
|
{ "Amb", MA_AMB },
|
|
{ "Spec", MA_SPEC },
|
|
{ "Hard", MA_HARD },
|
|
{ "SpTra", MA_SPTR },
|
|
{ "Ang", MA_ANG },
|
|
{ "HaSize", MA_HASIZE },
|
|
{ 0, 0 }
|
|
};
|
|
|
|
NamedEnum g_WO_ipocodes[] = {
|
|
{ "HorR", WO_HOR_R },
|
|
{ "HorG", WO_HOR_G },
|
|
{ "HorB", WO_HOR_B },
|
|
{ "ZenR", WO_ZEN_R },
|
|
{ "ZenG", WO_ZEN_G },
|
|
{ "ZenB", WO_ZEN_B },
|
|
{ "Expos", WO_EXPOS },
|
|
{ "Misi", WO_MISI },
|
|
{ "MisDi", WO_MISTDI },
|
|
{ "MisSta", WO_MISTSTA },
|
|
{ "MisHi", WO_MISTHI },
|
|
{ "StarR", WO_STAR_R },
|
|
{ "StarG", WO_STAR_G },
|
|
{ "StarB", WO_STAR_B },
|
|
{ "StarDi", WO_STARDIST },
|
|
{ "StarSi", WO_STARSIZE },
|
|
{ 0, 0 }
|
|
};
|
|
|
|
NamedEnum g_CA_ipocodes[] = {
|
|
{ "Lens", CAM_LENS },
|
|
{ "ClSta", CAM_STA },
|
|
{ "ClEnd", CAM_END },
|
|
{ 0, 0 }
|
|
};
|
|
|
|
PyObject *g_ipoBlockTypes; // global for ipo type container
|
|
PyObject *g_interpolationTypes; // global for interpolation type container
|
|
PyObject *g_extrapolationTypes; // global for extrapolation type container
|
|
|
|
typedef struct _PyBezTriple {
|
|
PyObject_VAR_HEAD
|
|
|
|
BezTriple bzt;
|
|
} PyBezTriple;
|
|
|
|
|
|
void pybzt_dealloc(PyObject *self) {
|
|
PyMem_DEL(self);
|
|
}
|
|
|
|
PyObject *pybzt_repr(PyObject *self) {
|
|
return PyString_FromString("[BezTriple]");
|
|
}
|
|
|
|
/* XXX */
|
|
|
|
NamedEnum bez_triple_flags[]= {
|
|
{"Free", HD_FREE},
|
|
{"Auto", HD_AUTO},
|
|
{"Vect", HD_VECT},
|
|
{"Align", HD_ALIGN},
|
|
{NULL}
|
|
};
|
|
|
|
DataBlockProperty BezTriple_Properties[]= {
|
|
{"h1", "vec[3][3]", DBP_TYPE_VEC, 0, 2.0, 0.0, {0,0}, {3,3,-sizeof(float)}},
|
|
{"pt", "vec[3][3]", DBP_TYPE_VEC, 0, 2.0, 0.0, {1,0}, {3,3,-sizeof(float)}},
|
|
{"h2", "vec[3][3]", DBP_TYPE_VEC, 0, 2.0, 0.0, {2,0}, {3,3,-sizeof(float)}},
|
|
|
|
{"f1", "f1", DBP_TYPE_CHA, 0, 0.0, 1.0},
|
|
{"f2", "f2", DBP_TYPE_CHA, 0, 0.0, 1.0},
|
|
{"f3", "f3", DBP_TYPE_CHA, 0, 0.0, 1.0},
|
|
|
|
{"h1Type", "h1", DBP_TYPE_SHO, 0, 0.0, 0.0, {0}, {0}, DBP_HANDLING_NENM, bez_triple_flags},
|
|
{"h2Type", "h2", DBP_TYPE_SHO, 0, 0.0, 0.0, {0}, {0}, DBP_HANDLING_NENM, bez_triple_flags},
|
|
|
|
{"h1t", "h1", DBP_TYPE_SHO, 0, 0.0, 0.0, {0}, {0}, DBP_HANDLING_NENM, bez_triple_flags},
|
|
{"h2t", "h2", DBP_TYPE_SHO, 0, 0.0, 0.0, {0}, {0}, DBP_HANDLING_NENM, bez_triple_flags},
|
|
|
|
{NULL}
|
|
};
|
|
|
|
PyObject *pybzt_getattr(PyObject *self, char *name) {
|
|
PyBezTriple *pybzt= (PyBezTriple *) self;
|
|
|
|
return datablock_getattr(BezTriple_Properties, "BezTriple", name, &pybzt->bzt);
|
|
}
|
|
|
|
int pybzt_setattr(PyObject *self, char *name, PyObject *ob) {
|
|
PyBezTriple *pybzt= (PyBezTriple *) self;
|
|
|
|
return datablock_setattr(BezTriple_Properties, "BezTriple", name, &pybzt->bzt, ob);
|
|
}
|
|
|
|
PyTypeObject PyBezTriple_Type = {
|
|
PyObject_HEAD_INIT(NULL)
|
|
0, /*ob_size*/
|
|
"BezTriple", /*tp_name*/
|
|
sizeof(PyBezTriple), /*tp_basicsize*/
|
|
0, /*tp_itemsize*/
|
|
/* methods */
|
|
(destructor) pybzt_dealloc, /*tp_dealloc*/
|
|
(printfunc) 0, /*tp_print*/
|
|
(getattrfunc) pybzt_getattr, /*tp_getattr*/
|
|
(setattrfunc) pybzt_setattr, /*tp_setattr*/
|
|
0, /*tp_compare*/
|
|
(reprfunc) pybzt_repr, /*tp_repr*/
|
|
0, /*tp_as_number*/
|
|
0, /*tp_as_sequence*/
|
|
0, /*tp_as_mapping*/
|
|
0, /*tp_hash*/
|
|
};
|
|
|
|
static char pybzt_create_doc[]= "() - Create a new BezTriple object";
|
|
PyObject *pybzt_create(PyObject *self, PyObject *args) {
|
|
PyBezTriple *py_bzt= PyObject_NEW(PyBezTriple, &PyBezTriple_Type);
|
|
// BezTriple *bzt= &py_bzt->bzt;
|
|
|
|
BPY_TRY(PyArg_ParseTuple(args, ""));
|
|
|
|
memset(&py_bzt->bzt,0,sizeof(py_bzt->bzt));
|
|
|
|
return (PyObject *) py_bzt;
|
|
}
|
|
|
|
PyObject *pybzt_from_bzt(BezTriple *bzt) {
|
|
PyBezTriple *py_bzt= PyObject_NEW(PyBezTriple, &PyBezTriple_Type);
|
|
|
|
memcpy(&py_bzt->bzt, bzt, sizeof(*bzt));
|
|
|
|
return (PyObject *) py_bzt;
|
|
}
|
|
|
|
|
|
typedef struct _PyIpoCurve {
|
|
PyObject_VAR_HEAD
|
|
|
|
IpoCurve *icu;
|
|
} PyIpoCurve;
|
|
|
|
|
|
/********************/
|
|
/* IpoCurve methods */
|
|
|
|
#undef MethodDef
|
|
#define MethodDef(func) _MethodDef(func, IpoCurve)
|
|
|
|
#define DICT_FROM_CONSTDICT(x) \
|
|
((constobject *) x)->dict
|
|
|
|
/** sets an enum int value 'by name' from the dictionary dict */
|
|
|
|
static PyObject *setEnum_fromDict(short *i, PyObject *dict, char *key, char *errmsg)
|
|
{
|
|
PyObject *p;
|
|
p = PyDict_GetItemString(dict, key);
|
|
if (!p) {
|
|
PyErr_SetString(PyExc_TypeError, errmsg);
|
|
return NULL;
|
|
}
|
|
|
|
*i = (short) PyInt_AsLong(p);
|
|
return BPY_incr_ret(Py_None);
|
|
}
|
|
|
|
static char IpoCurve_setInterpolation_doc[] =
|
|
"(type) - Set interpolation to one of: ['Constant', 'Linear', 'Bezier']";
|
|
|
|
static PyObject *IpoCurve_setInterpolation(PyObject *self, PyObject *args)
|
|
{
|
|
char *typename;
|
|
IpoCurve *ipocurve = (IpoCurve *) ((PyIpoCurve *) self)->icu;
|
|
|
|
BPY_TRY(PyArg_ParseTuple(args, "s", &typename));
|
|
|
|
return setEnum_fromDict(&ipocurve->ipo, DICT_FROM_CONSTDICT(g_interpolationTypes),
|
|
typename, "Improper interpolation type, see Ipo.InterpolationTypes");
|
|
|
|
}
|
|
|
|
static char IpoCurve_setExtrapolation_doc[] =
|
|
"(type) - Set interpolation to one of: ['Constant', 'Linear', 'Cyclic', 'CyclicLinear']";
|
|
|
|
static PyObject *IpoCurve_setExtrapolation(PyObject *self, PyObject *args)
|
|
{
|
|
char *typename;
|
|
IpoCurve *ipocurve = (IpoCurve *) ((PyIpoCurve *) self)->icu;
|
|
|
|
BPY_TRY(PyArg_ParseTuple(args, "s", &typename));
|
|
|
|
|
|
return setEnum_fromDict(&ipocurve->extrap, DICT_FROM_CONSTDICT(g_extrapolationTypes),
|
|
typename, "Improper extrapolation type, see Ipo.ExtrapolationTypes");
|
|
}
|
|
|
|
static char IpoCurve_getInterpolation_doc[] =
|
|
"() - Returns interpolation type";
|
|
|
|
static PyObject *IpoCurve_getInterpolation(PyObject *self, PyObject *args)
|
|
{
|
|
IpoCurve *ipocurve = (IpoCurve *) ((PyIpoCurve *) self)->icu;
|
|
|
|
switch (ipocurve->ipo) {
|
|
case IPO_CONST: return PyString_FromString("Constant");
|
|
case IPO_LIN: return PyString_FromString("Linear");
|
|
case IPO_BEZ: return PyString_FromString("Bezier");
|
|
default: return PyString_FromString("<not defined>");
|
|
}
|
|
}
|
|
|
|
static char IpoCurve_getExtrapolation_doc[] =
|
|
"() - Returns extrapolation type";
|
|
|
|
static PyObject *IpoCurve_getExtrapolation(PyObject *self, PyObject *args)
|
|
{
|
|
IpoCurve *ipocurve = (IpoCurve *) ((PyIpoCurve *) self)->icu;
|
|
|
|
switch (ipocurve->extrap) {
|
|
case IPO_HORIZ: return PyString_FromString("Constant");
|
|
case IPO_DIR: return PyString_FromString("Linear");
|
|
case IPO_CYCL: return PyString_FromString("Cyclic");
|
|
case IPO_CYCLX: return PyString_FromString("CyclicLinear");
|
|
default: return PyString_FromString("<not defined>");
|
|
}
|
|
|
|
}
|
|
|
|
static char IpoCurve_eval_doc[] =
|
|
"(time = <current frame>) - evaluates ipo at time 'time' and returns result\n\
|
|
(float). If 'time' is not specified, the current frame value is taken";
|
|
|
|
static PyObject *IpoCurve_eval(PyObject *self, PyObject *args)
|
|
{
|
|
PyIpoCurve *pIpocurve = (PyIpoCurve *) self;
|
|
float time = CurrentFrame;
|
|
|
|
BPY_TRY(PyArg_ParseTuple(args, "|f", &time));
|
|
|
|
return PyFloat_FromDouble(eval_icu(pIpocurve->icu, time));
|
|
}
|
|
|
|
static char IpoCurve_update_doc[] =
|
|
"() - update and recalculate IpoCurve";
|
|
|
|
static PyObject *IpoCurve_update(PyObject *self, PyObject *args)
|
|
{
|
|
|
|
BPY_TRY(PyArg_ParseTuple(args, ""));
|
|
|
|
testhandles_ipocurve(((PyIpoCurve *) self)->icu); // recalculate IPO
|
|
|
|
Py_INCREF(Py_None);
|
|
return Py_None;
|
|
}
|
|
|
|
static struct PyMethodDef IpoCurve_methods[] = {
|
|
MethodDef(setInterpolation),
|
|
MethodDef(getInterpolation),
|
|
MethodDef(setExtrapolation),
|
|
MethodDef(getExtrapolation),
|
|
MethodDef(eval),
|
|
MethodDef(update),
|
|
{NULL, NULL}
|
|
};
|
|
|
|
|
|
PyObject *IpoCurve_getattr(PyObject *self, char *name) {
|
|
PyIpoCurve *py_icu= (PyIpoCurve *) self;
|
|
IpoCurve *icu= py_icu->icu;
|
|
|
|
if (STREQ(name, "type")) {
|
|
return IpoCurve_getInterpolation(self, Py_BuildValue(""));
|
|
} else if (STREQ(name, "extend")) {
|
|
return IpoCurve_getExtrapolation(self, Py_BuildValue(""));
|
|
} else if (STREQ(name, "name")) {
|
|
char icu_name[32]= "";
|
|
|
|
switch (icu->blocktype) {
|
|
case ID_OB:
|
|
getname_ob_ei(icu->adrcode, icu_name, 0);
|
|
break;
|
|
case ID_MA:
|
|
getname_mat_ei(icu->adrcode, icu_name);
|
|
break;
|
|
case ID_WO:
|
|
getname_world_ei(icu->adrcode, icu_name);
|
|
break;
|
|
case ID_SEQ:
|
|
getname_seq_ei(icu->adrcode, icu_name);
|
|
break;
|
|
case ID_CU:
|
|
getname_cu_ei(icu->adrcode, icu_name);
|
|
break;
|
|
case ID_KE:
|
|
getname_key_ei(icu->adrcode, icu_name);
|
|
break;
|
|
case ID_LA:
|
|
getname_la_ei(icu->adrcode, icu_name);
|
|
break;
|
|
case ID_CA:
|
|
getname_cam_ei(icu->adrcode, icu_name);
|
|
break;
|
|
default:
|
|
return PyString_FromString("<unknown>");
|
|
}
|
|
|
|
return PyString_FromString(icu_name);
|
|
} else if (STREQ(name, "points")) {
|
|
PyObject *list= PyList_New(icu->totvert);
|
|
BezTriple *bzt= icu->bezt;
|
|
int i;
|
|
|
|
for (i=0; i<icu->totvert; i++) {
|
|
PyList_SetItem(list, i, pybzt_from_bzt(bzt));
|
|
bzt++;
|
|
}
|
|
|
|
return list;
|
|
}
|
|
return Py_FindMethod(IpoCurve_methods, (PyObject*)self, name);
|
|
}
|
|
|
|
int IpoCurve_setattr(PyObject *self, char *name, PyObject *ob) {
|
|
PyIpoCurve *py_icu= (PyIpoCurve *) self;
|
|
IpoCurve *icu= py_icu->icu;
|
|
|
|
if (STREQ(name, "points")) {
|
|
int i, len;
|
|
BezTriple *bzt;
|
|
|
|
if (!PySequence_Check(ob) || !BPY_check_sequence_consistency(ob, &PyBezTriple_Type))
|
|
return py_err_ret_int(PyExc_AttributeError, "Expected list of BezTriples");
|
|
|
|
len= PySequence_Length(ob);
|
|
|
|
if (icu->bezt) // free existing (IF)
|
|
MEM_freeN(icu->bezt);
|
|
|
|
icu->totvert= len;
|
|
if (len) icu->bezt= MEM_mallocN(len*sizeof(BezTriple), "beztriples");
|
|
|
|
bzt= icu->bezt;
|
|
for (i=0; i<len; i++) {
|
|
PyBezTriple *pybzt= (PyBezTriple*) PySequence_GetItem(ob, i);
|
|
|
|
memcpy(bzt, &pybzt->bzt, sizeof(BezTriple));
|
|
bzt++;
|
|
|
|
Py_DECREF(pybzt);
|
|
}
|
|
|
|
/* Twice for auto handles */
|
|
calchandles_ipocurve(icu);
|
|
calchandles_ipocurve(icu);
|
|
|
|
boundbox_ipocurve(icu);
|
|
sort_time_ipocurve(icu);
|
|
|
|
return 0;
|
|
}
|
|
|
|
PyErr_SetString(PyExc_AttributeError, name);
|
|
return -1;
|
|
}
|
|
|
|
void IpoCurve_dealloc(PyObject *self) {
|
|
PyMem_DEL(self);
|
|
}
|
|
|
|
PyObject *IpoCurve_repr(PyObject *self) {
|
|
char s[256];
|
|
sprintf (s, "[IpoCurve %.32s]",
|
|
PyString_AsString(IpoCurve_getattr(self, "name")));
|
|
return Py_BuildValue("s", s);
|
|
}
|
|
|
|
PyTypeObject PyIpoCurve_Type = {
|
|
PyObject_HEAD_INIT(NULL)
|
|
0, /*ob_size*/
|
|
"IpoCurve", /*tp_name*/
|
|
sizeof(PyIpoCurve), /*tp_basicsize*/
|
|
0, /*tp_itemsize*/
|
|
/* methods */
|
|
(destructor) IpoCurve_dealloc, /*tp_dealloc*/
|
|
(printfunc) 0, /*tp_print*/
|
|
(getattrfunc) IpoCurve_getattr, /*tp_getattr*/
|
|
(setattrfunc) IpoCurve_setattr, /*tp_setattr*/
|
|
0, /*tp_compare*/
|
|
(reprfunc) IpoCurve_repr, /*tp_repr*/
|
|
0, /*tp_as_number*/
|
|
0, /*tp_as_sequence*/
|
|
0, /*tp_as_mapping*/
|
|
0, /*tp_hash*/
|
|
};
|
|
|
|
PyObject *IpoCurve_from_icu(IpoCurve *icu) {
|
|
PyIpoCurve *ob= PyObject_NEW(PyIpoCurve, &PyIpoCurve_Type);
|
|
|
|
ob->icu= icu;
|
|
|
|
return (PyObject *) ob;
|
|
}
|
|
|
|
PyObject *make_icu_list (ListBase *curves) {
|
|
ListBase lb= *curves;
|
|
IpoCurve *icu= (IpoCurve *) lb.first;
|
|
PyObject *list= PyList_New(0);
|
|
PyObject *pyipo;
|
|
|
|
while (icu) {
|
|
pyipo = IpoCurve_from_icu(icu);
|
|
PyList_Append(list, pyipo);
|
|
Py_DECREF(pyipo);
|
|
icu= icu->next;
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
DataBlockProperty Ipo_Properties[]= {
|
|
{"curves", "curve", DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, 0, 0, make_icu_list},
|
|
{NULL}
|
|
};
|
|
|
|
|
|
/**********************/
|
|
/* Ipo module methods */
|
|
|
|
DATABLOCK_GET(Ipomodule, ipo, getIpoList())
|
|
|
|
static char Ipomodule_New_doc[] =
|
|
"(type, name = <default>) - Creates a new Ipo block of the specified type,\n\
|
|
which must be of the appropriate datablock ID type (e.g. ID_OB, ID_MA, ...)";
|
|
|
|
|
|
static PyObject *Ipomodule_New(PyObject *self, PyObject *args)
|
|
{
|
|
Ipo *ipo;
|
|
int type;
|
|
PyObject *p;
|
|
char *name = NULL, *typename;
|
|
|
|
BPY_TRY(PyArg_ParseTuple(args, "s|s", &typename, &name));
|
|
p = PyDict_GetItemString(((constobject *)g_ipoBlockTypes)->dict, typename);
|
|
if (!p) {
|
|
PyErr_SetString(PyExc_TypeError, "Improper Ipo type, see Ipo.Types");
|
|
return NULL;
|
|
}
|
|
|
|
type = PyInt_AsLong(p);
|
|
|
|
if (!name) {
|
|
switch(type) {
|
|
case ID_OB: name = "Objpo"; break;
|
|
case ID_MA: name = "MatIpo"; break;
|
|
case ID_SEQ: name = "SeqIpo"; break;
|
|
case ID_CU: name = "CurveIpo"; break;
|
|
case ID_KE: name = "KeyIpo"; break;
|
|
case ID_WO: name = "WorldIpo"; break;
|
|
case ID_LA: name = "LampIpo"; break;
|
|
case ID_CA: name = "CamIpo"; break;
|
|
case ID_SO: name = "SndIpo"; break;
|
|
case ID_AC: name = "ActionIpo"; break;
|
|
default:
|
|
PyErr_SetString(PyExc_TypeError, "Internal error, illegal type");
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
ipo = ipo_new(type, name);
|
|
return DataBlock_fromData(ipo);
|
|
}
|
|
|
|
#undef MethodDef
|
|
#define MethodDef(func) _MethodDef(func, Ipomodule)
|
|
struct PyMethodDef Ipomodule_methods[] = {
|
|
|
|
MethodDef(New),
|
|
MethodDef(get),
|
|
{"BezTriple", pybzt_create, METH_VARARGS, pybzt_create_doc},
|
|
|
|
{NULL, NULL}
|
|
};
|
|
|
|
/********************/
|
|
/* Ipoblock methods */
|
|
|
|
/* slow and inefficient lookup function , use proper dictionaries in future */
|
|
short code_lookup(NamedEnum *codetab, char *name)
|
|
{
|
|
int i = 0;
|
|
|
|
while(codetab[i].name)
|
|
{
|
|
if (!strcmp(codetab[i].name, name))
|
|
return codetab[i].num;
|
|
i++;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
static char Ipo_addCurve_doc[]=
|
|
"(type, curve = None) - adds IpoCurve 'curve' to the IpoBlock under type id 'type'";
|
|
PyObject *Ipo_addCurve(PyObject *self, PyObject *args)
|
|
{
|
|
|
|
Ipo *ipo = (Ipo *) ((DataBlock *) self)->data;
|
|
NamedEnum *lookup;
|
|
|
|
short code;
|
|
|
|
char *type;
|
|
PyIpoCurve *curve = NULL;
|
|
IpoCurve *ipocurve, *existingIpoCurve;
|
|
|
|
BPY_TRY(PyArg_ParseTuple(args, "s|O!", &type, &PyIpoCurve_Type, &curve));
|
|
|
|
switch (ipo->blocktype) {
|
|
case ID_OB:
|
|
lookup = g_OB_ipocodes;
|
|
break;
|
|
case ID_CA:
|
|
lookup = g_CA_ipocodes;
|
|
break;
|
|
case ID_MA:
|
|
lookup = g_MA_ipocodes;
|
|
break;
|
|
case ID_WO:
|
|
lookup = g_WO_ipocodes;
|
|
break;
|
|
default:
|
|
PyErr_SetString(PyExc_TypeError, "Ipo type not (YET) supported");
|
|
return NULL;
|
|
}
|
|
code = code_lookup(lookup, type);
|
|
if (code == -1) {
|
|
PyErr_SetString(PyExc_TypeError, "Unknown IpoCurve type");
|
|
return NULL;
|
|
}
|
|
|
|
if (!curve) {
|
|
ipocurve = ipocurve_new(); // malloc new ipocurve
|
|
} else { // add existing curve:
|
|
ipocurve = ipocurve_copy(curve->icu); // copy ipocurve
|
|
}
|
|
|
|
ipocurve->adrcode = code; // re-code ipo
|
|
ipocurve->blocktype = ipo->blocktype;
|
|
|
|
existingIpoCurve = ipo_findcurve(ipo, code);
|
|
if (existingIpoCurve) {
|
|
BLI_remlink(&(ipo->curve), existingIpoCurve); // remove existing
|
|
MEM_freeN(existingIpoCurve);
|
|
}
|
|
BLI_addtail(&(ipo->curve), ipocurve); // add curve to list
|
|
return IpoCurve_from_icu(ipocurve);
|
|
}
|
|
|
|
static char Ipo_update_doc[]=
|
|
"() - Recalculate the ipo and update linked objects";
|
|
|
|
PyObject *Ipo_update(PyObject *self, PyObject *args) {
|
|
DataBlock *ipoblock = (DataBlock *) self;
|
|
Key *key;
|
|
|
|
do_ipo((Ipo *) ipoblock->data);
|
|
|
|
/* here we should signal all objects with keys that the ipo changed */
|
|
|
|
key= getKeyList()->first;
|
|
while(key) {
|
|
if(key->ipo == (Ipo *)ipoblock->data) do_spec_key(key);
|
|
key= key->id.next;
|
|
}
|
|
|
|
return BPY_incr_ret(Py_None);
|
|
}
|
|
|
|
#undef MethodDef
|
|
#define MethodDef(func) _MethodDef(func, Ipo)
|
|
struct PyMethodDef Ipo_methods[] = {
|
|
MethodDef(addCurve),
|
|
MethodDef(update),
|
|
{NULL, NULL}
|
|
};
|
|
|
|
|
|
PyObject *initIpo(void)
|
|
{
|
|
PyObject *mod, *dict, *d;
|
|
|
|
mod= Py_InitModule(MODNAME(BLENDERMODULE) ".Ipo", Ipomodule_methods);
|
|
dict = PyModule_GetDict(mod);
|
|
|
|
// ipo block types
|
|
d = ConstObject_New();
|
|
PyDict_SetItemString(dict, "Types", d);
|
|
g_ipoBlockTypes = d;
|
|
|
|
insertConst(d, "Object", PyInt_FromLong(ID_OB));
|
|
insertConst(d, "Material", PyInt_FromLong(ID_MA));
|
|
insertConst(d, "Sequence", PyInt_FromLong(ID_SEQ));
|
|
insertConst(d, "Curve", PyInt_FromLong(ID_CU));
|
|
insertConst(d, "Key", PyInt_FromLong(ID_KE));
|
|
insertConst(d, "World", PyInt_FromLong(ID_WO));
|
|
insertConst(d, "Lamp", PyInt_FromLong(ID_LA));
|
|
insertConst(d, "Camera", PyInt_FromLong(ID_CA));
|
|
insertConst(d, "Sound", PyInt_FromLong(ID_SO));
|
|
insertConst(d, "Action", PyInt_FromLong(ID_AC));
|
|
|
|
// interpolation types:
|
|
d = ConstObject_New();
|
|
g_interpolationTypes = d;
|
|
PyDict_SetItemString(dict, "InterpolationTypes", d);
|
|
insertConst(d, "Constant", PyInt_FromLong(IPO_CONST));
|
|
insertConst(d, "Linear", PyInt_FromLong(IPO_LIN));
|
|
insertConst(d, "Bezier", PyInt_FromLong(IPO_BEZ));
|
|
|
|
d = ConstObject_New();
|
|
g_extrapolationTypes = d;
|
|
PyDict_SetItemString(dict, "ExtrapolationTypes", d);
|
|
insertConst(d, "Constant", PyInt_FromLong(IPO_HORIZ));
|
|
insertConst(d, "Linear", PyInt_FromLong(IPO_DIR));
|
|
insertConst(d, "Cyclic", PyInt_FromLong(IPO_CYCL));
|
|
insertConst(d, "CyclicLinear", PyInt_FromLong(IPO_CYCLX));
|
|
|
|
return mod;
|
|
}
|