diff options
author | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
---|---|---|
committer | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
commit | 12315f4d0e0ae993805f141f64cb8c73c5297311 (patch) | |
tree | 59b45827cd8293cfb727758989c7a74b40183974 /source/blender/bpython/intern/BPY_object.c |
Initial revisionv2.25
Diffstat (limited to 'source/blender/bpython/intern/BPY_object.c')
-rw-r--r-- | source/blender/bpython/intern/BPY_object.c | 499 |
1 files changed, 499 insertions, 0 deletions
diff --git a/source/blender/bpython/intern/BPY_object.c b/source/blender/bpython/intern/BPY_object.c new file mode 100644 index 00000000000..d0184f9b729 --- /dev/null +++ b/source/blender/bpython/intern/BPY_object.c @@ -0,0 +1,499 @@ +/** Object module; access to Object objects 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 "Python.h" +#include "BPY_macros.h" +#include "MEM_guardedalloc.h" +#include "opy_vector.h" /* matrix datatypes */ + +#include "b_interface.h" // most datatypes + +#include "opy_datablock.h" + +#include "BLI_arithb.h" /* Mat4Invert */ + +/* PROTOS */ + + +/* ------------------------------------------------------------------------ */ + +/**************************************************/ +/* Object properties for access by datablock code */ + +#define NULLFUNC 0 +#define NULLHANDLING 0 + +/* structure: see opy_datablock.h */ +/* attrname, DNA_membername, type stype, min, max, index,dlist, + handlingflag, extra1Ptr, extra2Ptr, extra3Ptr */ + +DataBlockProperty Object_Properties[]= { + {"LocX", "loc[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {0}, {3, -sizeof(float)}}, + {"LocY", "loc[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {1}, {3, -sizeof(float)}}, + {"LocZ", "loc[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {2}, {3, -sizeof(float)}}, + {"loc", "loc[3]", DBP_TYPE_VEC, 0, 3.0}, + + {"dLocX", "dloc[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {0}, {3, -sizeof(float)}}, + {"dLocY", "dloc[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {1}, {3, -sizeof(float)}}, + {"dLocZ", "dloc[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {2}, {3, -sizeof(float)}}, + {"dloc", "dloc[3]", DBP_TYPE_VEC, 0, 3.0}, + + {"RotX", "rot[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {0}, {3, -sizeof(float)}}, + {"RotY", "rot[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {1}, {3, -sizeof(float)}}, + {"RotZ", "rot[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {2}, {3, -sizeof(float)}}, + {"rot", "rot[3]", DBP_TYPE_VEC, 0, 3.0}, + + {"dRotX", "drot[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {0}, {3, -sizeof(float)}}, + {"dRotY", "drot[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {1}, {3, -sizeof(float)}}, + {"dRotZ", "drot[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {2}, {3, -sizeof(float)}}, + {"drot", "drot[3]", DBP_TYPE_VEC, 0, 3.0}, + + {"SizeX", "size[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {0}, {3, -sizeof(float)}}, + {"SizeY", "size[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {1}, {3, -sizeof(float)}}, + {"SizeZ", "size[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {2}, {3, -sizeof(float)}}, + {"size", "size[3]", DBP_TYPE_VEC, 0, 3.0}, + + {"dSizeX", "dsize[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {0}, {3, -sizeof(float)}}, + {"dSizeY", "dsize[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {1}, {3, -sizeof(float)}}, + {"dSizeZ", "dsize[3]", DBP_TYPE_FLO, 0, 0.0, 0.0, {2}, {3, -sizeof(float)}}, + {"dsize", "dsize[3]", DBP_TYPE_VEC, 0, 3.0}, + + {"EffX", "effx", DBP_TYPE_FLO, DBP_TYPE_FUN, 0.0, 0.0, {0}, {0}, DBP_HANDLING_FUNC, Object_special_getattr, 0, Object_special_setattr}, + {"EffY", "effy", DBP_TYPE_FLO, DBP_TYPE_FUN, 0.0, 0.0, {0}, {0}, DBP_HANDLING_FUNC, Object_special_getattr, 0, Object_special_setattr}, + {"EffZ", "effz", DBP_TYPE_FLO, DBP_TYPE_FUN, 0.0, 0.0, {0}, {0}, DBP_HANDLING_FUNC, Object_special_getattr, 0, Object_special_setattr}, + + {"Layer", "layer", DBP_TYPE_INT, DBP_TYPE_FUN, 0.0, 0.0, {0}, {0}, DBP_HANDLING_FUNC, Object_special_getattr, 0, Object_special_setattr}, + {"layer", "layer", DBP_TYPE_INT, DBP_TYPE_FUN, 0.0, 0.0, {0}, {0}, DBP_HANDLING_FUNC, Object_special_getattr, 0, Object_special_setattr}, + + {"parent", "*parent", DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, 0, 0, get_DataBlock_func}, + {"track", "*track", DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, 0, 0, get_DataBlock_func}, + {"data", "*data", DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, 0, 0, get_DataBlock_func}, + {"ipo", "*ipo", DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, 0, 0, get_DataBlock_func}, + + {"mat", "matrix", DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, DBP_HANDLING_FUNC, Object_special_getattr, newMatrixObject}, + {"matrix", "matrix", DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, DBP_HANDLING_FUNC, Object_special_getattr, newMatrixObject}, + + {"colbits", "colbits", DBP_TYPE_SHO, 0, 0.0, 0.0}, + {"drawType", "dt", DBP_TYPE_CHA, 0, 0.0, 0.0}, + {"drawMode", "dtx", DBP_TYPE_CHA, 0, 0.0, 0.0}, + + {NULL} +}; + +/*************************/ +/* Object module methods */ + +DATABLOCK_GET(Objectmodule, object, getObjectList()) + +char Objectmodule_New_doc[] = "(type) - Add a new object of type 'type' in the current scene"; +static PyObject *Objectmodule_New(PyObject *self, PyObject *args) +{ + Object *ob; + int type; + + if (!PyArg_ParseTuple(args, "i", &type)) { + PyErr_SetString(PyExc_TypeError, "type expected"); + return 0; + } + /* add object */ + ob = object_new(type); + return DataBlock_fromData(ob); +} + +static char Objectmodule_getSelected_doc[]= +"() - Returns a list of selected Objects in the active layer(s)\n\ +The active object is the first in the list, if visible"; + +static PyObject *Objectmodule_getSelected (PyObject *self, PyObject *args) +{ + PyObject *ob, *list; + Base *base; + Object *tmp; + + list= PyList_New(0); + + if (ActiveBase && SelectedAndLayer(ActiveBase)) { + tmp = ActiveObject; /* active object is first in list */ + if (!tmp) goto no_selection; + ob = DataBlock_fromData(tmp); + PyList_Append(list, ob); Py_DECREF(ob); // because previous call increfs + } + + base = FirstBase; + while (base) { + if (SelectedAndLayer(base) && base != ActiveBase) { + PyObject *ob = DataBlock_fromData(ObjectfromBase(base)); + if (!ob) goto no_selection; + PyList_Append(list, ob); Py_DECREF(ob); + } + base= base->next; + } + return list; +no_selection: + Py_DECREF(list); + Py_INCREF(Py_None); + return Py_None; + +} + + +struct PyMethodDef Objectmodule_methods[] = { + {"New", Objectmodule_New, METH_VARARGS, Objectmodule_New_doc}, + // emulation : + {"Get", Objectmodule_get, METH_VARARGS, Objectmodule_get_doc}, // XXX + {"get", Objectmodule_get, METH_VARARGS, Objectmodule_get_doc}, + {"getSelected", Objectmodule_getSelected, METH_VARARGS, Objectmodule_getSelected_doc}, + {NULL, NULL} +}; + +/*************************/ +/* Object object methods */ + +/* Object_get is defined as macro; see opy_datablock.h */ + + +static char Object_getType_doc[] = "() - returns Object type"; + +static PyObject *Object_getType(PyObject *self, PyObject *args) +{ + Object *ob= PYBLOCK_AS_OBJECT(self); + return Py_BuildValue("i", (short) ob->type); +} + +static char Object_getMatrix_doc[] = "() - returns 4D matrix of object"; + +static PyObject *Object_getMatrix(PyObject *self, PyObject *args) +{ + Object *ob= PYBLOCK_AS_OBJECT(self); + return newMatrixObject(ob->obmat); +} + +static char Object_getInverseMatrix_doc[] = "() - returns inverse 4D matrix of object"; + +static PyObject *Object_getInverseMatrix(PyObject *self, PyObject *args) +{ + Object *ob= PYBLOCK_AS_OBJECT(self); + float inverse[4][4]; + Mat4Invert(inverse, ob->obmat); + return newMatrixObject(inverse); +} + +static char Object_clrParent_doc[]= +"(mode = 0, fast = 0) - clears parent object.\n\ +If specified:\n\ + mode 2: keep object transform\n\ + fast > 0: don't update scene hierarchy (faster)\n\ +"; + +static PyObject *Object_clrParent(PyObject *self, PyObject *args) +{ + int mode = 0, ret; + int fast = 0; + Object *ob= PYBLOCK_AS_OBJECT(self); + + BPY_TRY(PyArg_ParseTuple(args, "|ii", &mode, &fast)); + ret = object_clrParent(ob, mode, fast); + return Py_BuildValue("i", ret); +} + +DATABLOCK_ASSIGN_IPO(Object, object) // defines Object_assignIpo + +static char Object_makeParent_doc[]= +"([obj1, obj2, ...], mode = 0, fast = 0) - makes 'self' a parent of the\n\ +objects in the list.\n\ +If specified:\n\ + mode <> 0: do not clear parent inverse\n\ + fast <> 0 : do not update scene hierarchy (faster)\n\ +\n\ +If fast is set, you will have to call Scene.getCurrent.update() before\n\ +redraw."; + +static PyObject *Object_makeParent(PyObject *self, PyObject *args) +{ + int i, ret; + PyObject *list; + int noninverse = 0; + int fast = 0; + + DataBlock *parblk = (DataBlock*) self; + + BPY_TRY(PyArg_ParseTuple(args, "O|ii", &list, &noninverse, &fast)); + if (!PySequence_Check(list)){ + PyErr_SetString(PyExc_TypeError, "expects a list of objects"); + return 0; + } + + for (i = 0; i < PySequence_Length(list); i ++) { + DataBlock *childblk = (DataBlock *) PySequence_GetItem(list, i); + + if (!DataBlock_Check(childblk)) { + PyErr_SetString(PyExc_TypeError, "Object Type expected"); + return 0; + } + ret = object_makeParent((Object *) parblk->data, (Object *) childblk->data, noninverse, fast); + + Py_DECREF((PyObject *) childblk); // don't need it anymore + if (ret == 0) { // could not parent + PyErr_SetString(PyExc_RuntimeError, "parenting failed!"); + return 0; + } + } + + if (PyErr_Occurred()) { + PyErr_Print(); + } + return Py_BuildValue("i", 1); +} + +static char Object_getMaterials_doc[] = "() - returns a list of object materials"; + +static PyObject *Object_getMaterials(PyObject *self, PyObject *args) +{ + DataBlock *objectblk = (DataBlock*) self; + Object *object = PYBLOCK_AS_OBJECT(objectblk); + return PyList_fromMaterialList(object->mat, object->totcol); +} + +static char Object_setMaterials_doc[] = "(materialList) - sets object materials"; + +static PyObject *Object_setMaterials(PyObject *self, PyObject *args) +{ + int len; + int ret; + DataBlock *objectblk = (DataBlock*) self; + Object *object = PYBLOCK_AS_OBJECT(objectblk); + PyObject *list; + Material **matlist; + + BPY_TRY(PyArg_ParseTuple(args, "O!", &PyList_Type, &list)); + len = PySequence_Length(list); + if (len) { + matlist = newMaterialList_fromPyList(list); + if (!matlist) { + PyErr_SetString(PyExc_TypeError, + "materialList must be a list of valid materials!"); + return 0; + } + ret = object_setMaterials(object, matlist, len); + } else { + ret = 0; + } + return Py_BuildValue("i", ret); +} + +static char Object_copy_doc[] = "() - returns a copy of the object, sharing the same data"; + +static PyObject *Object_copy(PyObject *self, PyObject *args) +{ + Object *new; + + DataBlock *objectblk = (DataBlock*) self; + Object *object = PYBLOCK_AS_OBJECT(objectblk); + + new = object_copy(object); + return DataBlock_fromData(new); +} + +static char Object_shareFrom_doc[] = "(obj) - link data of 'self' with data of 'obj' -- \n\ +only if of same type!"; + +static PyObject *Object_shareFrom(PyObject *self, PyObject *args) +{ + DataBlock *blockA = (DataBlock*) self; + DataBlock *blockB; + Object *object, *other; + int t; + + BPY_TRY(PyArg_ParseTuple(args, "O!", &DataBlock_Type, &blockB)); + + if (!DataBlock_isType(blockB, ID_OB)) { + PyErr_SetString(PyExc_TypeError, "Argument 1 is not of type 'Object'"); + return NULL; + } + + object = PYBLOCK_AS_OBJECT(blockA); + other = PYBLOCK_AS_OBJECT(blockB); + + if (other->type != object->type) { + PyErr_SetString(PyExc_TypeError, "Objects are not of same data type"); + return NULL; + } + t = object->type; + switch (t) { + case OB_MESH: + return Py_BuildValue("i", object_linkdata(object, other->data)); + default: + PyErr_SetString(PyExc_TypeError, "Type not supported"); + return NULL; + } +} + +/******************/ +/* get & set attr */ + +static float g_zero_float= 0.0; + +/* Object attributes functions which require getter/setter C functions + different from the access provided by DataBlock support */ + +/* get special attributes through datablock property structure */ + +void *Object_special_getattr(void *vdata, char *name) +{ + Object *ob= (Object *) vdata; + int scriptflag; + + if (STREQ(name, "layer")) { + return &ob->lay; + + } else if (strncmp(name, "eff", 3)==0) { + Ika *ika= ob->data; + + if (ob->type==OB_IKA && ika) { + if (name[3]=='x') return &ika->effg[0]; + else if (name[3]=='y') return &ika->effg[1]; + else if (name[3]=='z') return &ika->effg[2]; + } + + return &g_zero_float; + /* these only for compatibiliy... XXX */ + } else if (STREQ(name, "matrix")) { + scriptflag = during_script(); + disable_where_script(1); + where_is_object(ob); + disable_where_script(scriptflag); + + return &ob->obmat; + } else if (STREQ(name, "inverse") || STREQ(name, "inverseMatrix")) { + return Object_getInverseMatrix(vdata, 0); + } + /* end compatibility */ + + PyErr_SetString(PyExc_AttributeError, name); + return NULL; +} + +int Object_special_setattr(void *vdata, char *name, PyObject *py_ob) +{ + Object *ob= (Object *) vdata; + + if (STREQ(name, "layer")) { + Base *base; + int ival; + + if (!PyArg_Parse(py_ob, "i", &ival)) return -1; + + ob->lay= ival; + // TODO this is old stuff, maybe move to update routine at end of + // script execution ? + base= (G.scene->base.first); + while (base) { + if (base->object == ob) base->lay= ob->lay; + base= base->next; + } + // end TODO + + return 0; + } else if (strncmp(name, "eff", 3)==0) { + Ika *ika= ob->data; + float fval; + + if (!PyArg_Parse(py_ob, "f", &fval)) return -1; + + if (ob->type==OB_IKA && ika) { + if (name[3]=='x') ika->effg[0]= fval; + else if (name[3]=='y') ika->effg[1]= fval; + else if (name[3]=='z') ika->effg[2]= fval; + + itterate_ika(ob); + } + return 0; + } + + PyErr_SetString(PyExc_AttributeError, name); + return -1; +} + + + +#undef MethodDef +#define MethodDef(func) _MethodDef(func, Object) + +struct PyMethodDef Object_methods[] = { + MethodDef(makeParent), + MethodDef(copy), + MethodDef(shareFrom), + MethodDef(getMatrix), + MethodDef(getType), + MethodDef(getInverseMatrix), + MethodDef(clrParent), + MethodDef(assignIpo), + MethodDef(clrIpo), + MethodDef(getMaterials), + MethodDef(setMaterials), + {NULL, NULL} +}; + +#undef BPY_ADDCONST +#define BPY_ADDCONST(dict, name) insertConst(dict, #name, PyInt_FromLong(OB_##name)) + +PyObject *initObject(void) +{ + PyObject *mod, *dict, *d; + + mod= Py_InitModule(MODNAME(BLENDERMODULE) ".Object", Objectmodule_methods); + dict= PyModule_GetDict(mod); + d = ConstObject_New(); + PyDict_SetItemString(dict, "Types", d); + BPY_ADDCONST(d, EMPTY); + BPY_ADDCONST(d, MESH); + BPY_ADDCONST(d, LAMP); + BPY_ADDCONST(d, CAMERA); + + d = ConstObject_New(); + PyDict_SetItemString(dict, "DrawTypes", d); + /* dt flags */ + BPY_ADDCONST(d, BOUNDBOX); + BPY_ADDCONST(d, WIRE); + BPY_ADDCONST(d, SOLID); + BPY_ADDCONST(d, SHADED); + BPY_ADDCONST(d, TEXTURE); + d = ConstObject_New(); + PyDict_SetItemString(dict, "DrawModes", d); + /* dtx flags */ + BPY_ADDCONST(d, BOUNDBOX); + BPY_ADDCONST(d, AXIS); + BPY_ADDCONST(d, TEXSPACE); + insertConst(d, "NAME", PyInt_FromLong(OB_DRAWNAME)); + return mod; +} + |