diff options
Diffstat (limited to 'source/blender/bpython/intern/opy_datablock.c')
-rw-r--r-- | source/blender/bpython/intern/opy_datablock.c | 1303 |
1 files changed, 0 insertions, 1303 deletions
diff --git a/source/blender/bpython/intern/opy_datablock.c b/source/blender/bpython/intern/opy_datablock.c deleted file mode 100644 index 3e63e2d5610..00000000000 --- a/source/blender/bpython/intern/opy_datablock.c +++ /dev/null @@ -1,1303 +0,0 @@ -/* Datablock handling code. This handles the generic low level access to Blender - Datablocks. */ - -/* - * $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 ***** - */ - -/************************************************************************** - * This code provides low level, generalized access to the Blender Datablock - * objects. It basically creates a descriptor Python Object of type 'DataBlock' - * for each requested Blender datablock. - * This introduces the question of synchronization, for example: - * What happens if an Object is deleted? - * - * Blender Objects have their own 'reference counting', e.g. a Mesh datablock - * used by two Objects has a user count of 2. Datablocks with user count of 0 - * are not saved to Disk -- this is the current way Blender does - * 'garbage collection' - * Therefore, an object should normally not be deleted by Python, but rather - * unlinked from its parent object. - * Still, for other objects like Scene or Text objects, deletion from 'Main' - * is desired. - * The current workaround: - - * Some objects can be explicitely deleted (not recommended, but possible) -- - * they have a user count of 1, even if they are used by objects in some way, - * for example Text objects which are used by any other Blender object - * through a ScriptLink. - * - * Objects that are deleted through Python end up with a 'dead' descriptor; - * accessing the descriptor after deletion causes a Python exception. - * - * NASTY UGLY DIRTY, VUILE, DRECKIGES AND STILL REMAINING PROBLEM: - * - * It is (in the current API) possible to construct the case, that an - * Object is deleted in Blender, but the Python descriptor does not know - * about this. Accessing the descriptor (which simply contains a pointer to - * the raw datablock struct) will most probably end in colourful joy. - * - * TODO: - * possible solutions: - * - rewrite datablock handling that way, that the descriptor uses an id - * tag to retrieve that pointer through a getPointerbyID() function - * (if the object exists!) on each access. Slow. - * - make sure that deletion always happends by the descriptor and never - * delete the raw datastructure. This solution would imply a major - * redesign of user action handling (GUI actions calling python). - * Not likely to happen...better fusion raw and python object in this case. - * After all, still somewhat dirty. - * - make sure that no deletion can happen in Blender while a script - * still accesses the raw data - i.e. implement user counting of raw - * objects with descriptors. This would need an implementation of - * garbage collection in Blender. This might sound like the most feasible - * solution... - */ - - -#include "Python.h" -#include "BPY_macros.h" - -#include "opy_datablock.h" -#include "opy_nmesh.h" - -#include "opy_vector.h" /* matrix datatypes */ - -#include "BPY_tools.h" -#include "BPY_types.h" -#include "BPY_main.h" - -#include "MEM_guardedalloc.h" - -#include "b_interface.h" /* needed for most of the DNA datatypes */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - - -/* ---------------------------------------------------------------------- */ - -/*********************/ -/* Camera Datablocks */ - -DATABLOCK_GET(Cameramodule, camera, getCameraList()) - -static char Cameramodule_New_doc[] = -"() - returns new Camera object"; - -PyObject *Cameramodule_New (PyObject *self, PyObject *args) -{ - Camera *obj; - obj = camera_new(); - return DataBlock_fromData(obj); -} - -#ifdef FUTURE_PYTHON_API - -DataBlockProperty Camera_Properties[]= { - {"lens", "lens", DBP_TYPE_FLO, 0, 1.0, 250.0}, - {"clipStart","clipsta", DBP_TYPE_FLO, 0, 0.0, 100.0}, - {"clipEnd", "clipend", DBP_TYPE_FLO, 0, 1.0, 5000.0}, - {"type", "type", DBP_TYPE_SHO, 0, 0.0, 0.0}, - {"mode", "flag", DBP_TYPE_SHO, 0, 0.0, 0.0}, - - {"ipo", "*ipo", DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, 0, 0, get_DataBlock_func}, - - {NULL} -}; - -#else - -DataBlockProperty Camera_Properties[]= { - {"Lens", "lens", DBP_TYPE_FLO, 0, 1.0, 250.0}, - {"ClSta", "clipsta", DBP_TYPE_FLO, 0, 0.0, 100.0}, - {"ClEnd", "clipend", DBP_TYPE_FLO, 0, 1.0, 5000.0}, - - {"ipo", "*ipo", DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, 0, 0, get_DataBlock_func}, - - {NULL} -}; - -#endif - -static struct PyMethodDef Cameramodule_methods[] = { - {"New", Cameramodule_New, METH_VARARGS, Cameramodule_New_doc}, - {"get", Cameramodule_get, METH_VARARGS, Cameramodule_get_doc}, - {NULL, NULL} -}; - -DATABLOCK_ASSIGN_IPO(Camera, camera) // defines Camera_assignIpo - -static struct PyMethodDef Camera_methods[] = { - {"clrIpo", Camera_clrIpo, METH_VARARGS, Camera_clrIpo_doc}, - {"assignIpo", Camera_assignIpo, METH_VARARGS, Camera_assignIpo_doc}, - {NULL, NULL} -}; - -/***********************/ -/* Material Datablocks */ - - -/** returns a pointer to a new (malloced) material list created from - * a Python material list - */ - -Material **newMaterialList_fromPyList(PyObject *list) -{ - int i, len; - DataBlock *block = 0; - Material *mat; - Material **matlist; - - len = PySequence_Length(list); - if (len > 16) len = 16; - - matlist = newMaterialList(len); - - for (i= 0; i < len; i++) { - - block= (DataBlock *) PySequence_GetItem(list, i); - - if (DataBlock_isType(block, ID_MA)) { - mat = (Material *) block->data; - matlist[i] = mat; - } else { - // error; illegal type in material list - Py_DECREF(block); - MEM_freeN(matlist); - return NULL; - } - Py_DECREF(block); - } - return matlist; -} - -/** Return Python List from material pointer list 'matlist' with length - * 'len' - * - */ - -PyObject *PyList_fromMaterialList(Material **matlist, int len) -{ - PyObject *list; - int i; - - list = PyList_New(0); - if (!matlist) return list; - - for (i = 0; i < len; i++) { - Material *mat= matlist[i]; - PyObject *ob; - - if (mat) { - ob = DataBlock_fromData(mat); - PyList_Append(list, ob); - Py_DECREF(ob); // because Append increfs! - } - } - return list; -} - -DATABLOCK_GET(Materialmodule, material, getMaterialList()) - -DATABLOCK_NEW(Materialmodule, Material, material_new()) - -static struct PyMethodDef Materialmodule_methods[] = { - {"get", Materialmodule_get, METH_VARARGS, Materialmodule_get_doc}, - {"New", Materialmodule_New, METH_VARARGS, Materialmodule_New_doc}, - {NULL, NULL} -}; - -DATABLOCK_ASSIGN_IPO(Material, material) - -static struct PyMethodDef Material_methods[] = { - {"clrIpo", Material_clrIpo, METH_VARARGS, Material_clrIpo_doc}, - {"assignIpo", Material_assignIpo, METH_VARARGS, Material_assignIpo_doc}, - {NULL, NULL} -}; - -#ifdef FUTURE_PYTHON_API - -DataBlockProperty Material_Properties[]= { - {"R", "r", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"G", "g", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"B", "b", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"specR", "specr", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"specG", "specg", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"specB", "specb", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"mirR", "mirr", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"mirG", "mirg", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"mirB", "mirb", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"ref", "ref", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"alpha", "alpha", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"emit", "emit", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"amb", "amb", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"spec", "spec", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"specTransp", "spectra", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"haloSize", "hasize", DBP_TYPE_FLO, 0, 0.0, 10000.0}, - - {"mode", "mode", DBP_TYPE_INT, 0, 0.0, 0.0}, - {"hard", "har", DBP_TYPE_SHO, 0, 1.0, 128.0}, - - {"ipo", "*ipo", DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, 0, 0, get_DataBlock_func}, - - {NULL} -}; - -#else - -DataBlockProperty Material_Properties[]= { - {"R", "r", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"G", "g", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"B", "b", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"SpecR", "specr", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"SpecG", "specg", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"SpecB", "specb", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"MirR", "mirr", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"MirG", "mirg", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"MirB", "mirb", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"Ref", "ref", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"Alpha", "alpha", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"Emit", "emit", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"Amb", "amb", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"Spec", "spec", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"SpTra", "spectra", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"HaSize", "hasize", DBP_TYPE_FLO, 0, 0.0, 10000.0}, - - {"Mode", "mode", DBP_TYPE_INT, 0, 0.0, 0.0}, - {"Hard", "har", DBP_TYPE_SHO, 0, 1.0, 128.0}, - - {"ipo", "*ipo", DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, 0, 0, get_DataBlock_func}, - - {NULL} -}; - -#endif - -/*******************/ -/* Lamp Datablocks */ - -DATABLOCK_GET(Lampmodule, lamp, getLampList()) - -// DATABLOCK_NEW(Lampmodule, Lamp, lamp_new()) - -static char Lampmodule_New_doc[] = -"() - returns new Lamp object"; - -PyObject *Lampmodule_New (PyObject *self, PyObject *args) -{ - Lamp *obj; - obj = lamp_new(); - return DataBlock_fromData(obj); -} - -#ifdef FUTURE_PYTHON_API - -DataBlockProperty Lamp_Properties[]= { - {"mode", "mode", DBP_TYPE_SHO, 0, 0.0, 0.0}, - {"type", "type", DBP_TYPE_SHO, 0, 0.0, 0.0}, - {"R", "r", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"G", "g", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"B", "b", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"energy", "energy", DBP_TYPE_FLO, 0, 0.0, 10.0}, - {"dist", "dist", DBP_TYPE_FLO, 0, 0.01, 5000.0}, - {"spotSize", "spotsize", DBP_TYPE_FLO, 0, 1.0, 180.0}, - {"spotBlend", "spotblend", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"haloInt", "haint", DBP_TYPE_FLO, 0, 0.0, 5.0}, - {"quad1", "att1", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"quad2", "att2", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"bufferSize", "bufsize", DBP_TYPE_SHO, 0, 0.0, 0.0}, - {"samples", "samp", DBP_TYPE_SHO, 0, 1.0, 16.0}, - {"haloStep", "shadhalostep", DBP_TYPE_SHO, 0, 0.0, 12.0}, - {"clipStart", "clipsta", DBP_TYPE_FLO, 0, 0.1, 5000.0}, - {"clipEnd", "clipend", DBP_TYPE_FLO, 0, 0.1, 5000.0}, - {"bias", "bias", DBP_TYPE_FLO, 0, 0.01, 5.0}, - {"softness", "soft", DBP_TYPE_FLO, 0, 1.00, 100.0}, - - {"ipo", "*ipo", DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, 0, 0, get_DataBlock_func}, - - {NULL} -}; -#else - -DataBlockProperty Lamp_Properties[]= { - {"mode", "mode", DBP_TYPE_SHO, 0, 0.0, 0.0}, - {"type", "type", DBP_TYPE_SHO, 0, 0.0, 0.0}, - {"R", "r", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"G", "g", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"B", "b", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"Energ", "energy", DBP_TYPE_FLO, 0, 0.0, 10.0}, - {"Dist", "dist", DBP_TYPE_FLO, 0, 0.01, 5000.0}, - {"SpotSi", "spotsize", DBP_TYPE_FLO, 0, 1.0, 180.0}, - {"SpotBl", "spotblend", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"HaloInt", "haint", DBP_TYPE_FLO, 0, 1.0, 5.0}, - {"Quad1", "att1", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"Quad2", "att2", DBP_TYPE_FLO, 0, 0.0, 1.0}, - - {"ipo", "*ipo", DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, 0, 0, get_DataBlock_func}, - - {NULL} -}; - -#endif - - -static struct PyMethodDef Lampmodule_methods[] = { - {"New", Lampmodule_New, METH_VARARGS, Lampmodule_New_doc}, - {"get", Lampmodule_get, METH_VARARGS, Lampmodule_get_doc}, -#ifdef CURRENT_PYTHON_API - {"Get", Lampmodule_get, METH_VARARGS, Lampmodule_get_doc}, -#endif - {NULL, NULL} -}; - -DATABLOCK_ASSIGN_IPO(Lamp, lamp) // defines Lamp_assignIpo - -static struct PyMethodDef Lamp_methods[] = { - {"clrIpo", Lamp_clrIpo, METH_VARARGS, Lamp_clrIpo_doc}, - {"assignIpo", Lamp_assignIpo, METH_VARARGS, Lamp_assignIpo_doc}, - {NULL, NULL} -}; - -/********************/ -/* World Datablocks */ - -DATABLOCK_GET(Worldmodule, world, getWorldList() ) - -#ifdef FUTURE_PYTHON_API - -DataBlockProperty World_Properties[]= { - - {"mode", "mode", DBP_TYPE_SHO, 0, 0.0, 0.0}, - {"skyType", "skytype", DBP_TYPE_SHO, 0, 0.0, 0.0}, - {"mistType", "mistype", DBP_TYPE_SHO, 0, 0.0, 0.0}, - {"horR", "horr", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"horG", "horg", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"horB", "horb", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"ambR", "ambr", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"ambG", "ambg", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"ambB", "ambb", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"zenR", "zenr", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"zenG", "zeng", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"zenB", "zenb", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"exposure", "exposure", DBP_TYPE_FLO, 0, 0.0, 5.0}, - {"mistStart", "miststa", DBP_TYPE_FLO, 0, 0.0, 1000.0}, - {"mistDepth", "mistdist", DBP_TYPE_FLO, 0, 0.0, 1000.0}, - {"mistHeight", "misthi", DBP_TYPE_FLO, 0, 0.0, 100.0}, - {"starDensity", "stardist", DBP_TYPE_FLO, 0, 2.0, 1000.0}, - {"starMinDist", "starmindist", DBP_TYPE_FLO, 0, 0.0, 1000.0}, - {"starSize", "starsize", DBP_TYPE_FLO, 0, 0.0, 10.0}, - {"starColNoise", "starcolsize", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"gravity", "gravity", DBP_TYPE_FLO, 0, 0.0, 25.0}, - - {"ipo", "*ipo", DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, 0, 0, get_DataBlock_func}, - - {NULL} -}; - -#else - -DataBlockProperty World_Properties[]= { - {"HorR", "horr", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"HorG", "horg", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"HorB", "horb", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"ZenR", "zenr", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"ZenG", "zeng", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"ZenB", "zenb", DBP_TYPE_FLO, 0, 0.0, 1.0}, - {"Expos", "exposure", DBP_TYPE_FLO, 0, 0.0, 5.0}, - {"MisSta", "miststa", DBP_TYPE_FLO, 0, 0.0, 1000.0}, - {"MisDi", "mistdist", DBP_TYPE_FLO, 0, 0.0, 1000.0}, - {"MisHi", "misthi", DBP_TYPE_FLO, 0, 0.0, 100.0}, - {"StarDi", "stardist", DBP_TYPE_FLO, 0, 2.0, 1000.0}, - {"StarSi", "starsize", DBP_TYPE_FLO, 0, 0.0, 10.0}, - - {"ipo", "*ipo", DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, 0, 0, get_DataBlock_func}, - - {NULL} -}; - -#endif - -static char Worldmodule_getActive_doc[]="() - Returns the active world"; -static PyObject *Worldmodule_getActive (PyObject *self, PyObject *args) -{ - if (scene_getCurrent()->world) - return DataBlock_fromData(scene_getCurrent()->world); - else - return BPY_incr_ret(Py_None); -} - -static struct PyMethodDef Worldmodule_methods[] = { - // these for compatibility... - {"get", Worldmodule_get, METH_VARARGS, Worldmodule_get_doc}, -#ifdef CURRENT_PYTHON_API - {"Get", Worldmodule_get, METH_VARARGS, Worldmodule_get_doc}, -#endif - {"getCurrent", Worldmodule_getActive, METH_VARARGS, Worldmodule_getActive_doc}, - {NULL, NULL} -}; - - - -/* XXX these should go elsewhere */ - -PyObject *BPY_PyList_FromIDList(ListBase *list, DBConvertfunc convertfunc) -{ - PyObject *pylist= PyList_New(BLI_countlist(list)); - ID *id = list->first; - - int i=0; - - while (id) { - PyObject *ob= convertfunc(id); - - if (!ob) { - Py_DECREF(pylist); - return NULL; - } - PyList_SetItem(pylist, i, ob); - id = id->next; i++; - } - return pylist; -} - - -PyObject *py_find_from_list(ListBase *list, PyObject *args) { - char *name= NULL; - ID *id = list->first; - BPY_TRY(PyArg_ParseTuple(args, "|s", &name)); - - if (name) { - while (id) { - if (strcmp(name, getIDName(id))==0) - return DataBlock_fromData(id); - - id= id->next; - } - return BPY_incr_ret(Py_None); - - } else - return BPY_PyList_FromIDList(list, DataBlock_fromData); -} - -PyObject *named_enum_get(int val, NamedEnum *enums) { - while (enums->name) { - if (enums->num == val) return PyString_FromString(enums->name); - enums++; - } - PyErr_SetString(PyExc_AttributeError, "Internal error, Unknown enumerated type"); - return NULL; -} - -int named_enum_set(char *name, NamedEnum *enums) { - while (enums->name) { - if (STREQ(enums->name, name)) - return enums->num; - enums++; - } - - return -1; -} - -static int calc_offset_subsize(int *dlist, int *idx, int *subsize) { - int n= *dlist; - - if (n<=0) { - *subsize= -n; - return 0; - } else { - int ss; - int off= calc_offset_subsize(dlist+1, idx+1, &ss); - - *subsize= n*ss; - return off + (*idx)*ss; - } -} - -static int calc_offset(int *dlist, int *idx) { - int subsize; - return calc_offset_subsize(dlist, idx, &subsize); -} - -static void *get_db_ptr(DataBlockProperty *prop, char *structname, void *struct_ptr) { - int offset= BLO_findstruct_offset(structname, prop->struct_name); - void *ptr= struct_ptr; - - if (offset==-1) { - BPY_warn(("Internal error, Invalid prop entry\n")); - return NULL; - } - - ptr= (void *) (((char *)ptr) + offset); - - offset= calc_offset(prop->dlist, prop->idx); - ptr= (void *) (((char *)ptr) + offset); - - return ptr; -} - -PyObject *datablock_getattr(DataBlockProperty *props, char *structname, char *name, void *struct_ptr) { - if (STREQ(name, "properties") || STREQ(name, "__members__")) { - PyObject *l= PyList_New(0); - DataBlockProperty *p= props; - - while (p->public_name) { - PyList_Append(l, PyString_FromString(p->public_name)); - p++; - } - - return l; - } - - while (props->public_name) { - if (STREQ(name, props->public_name)) { - void *ptr = struct_ptr; - int val; - DBPtrToObFP conv_fp; - - if (props->handling==DBP_HANDLING_NONE || - props->handling==DBP_HANDLING_NENM) { - ptr= get_db_ptr(props, structname, struct_ptr); - if (!ptr) return NULL; - - } else if (props->handling==DBP_HANDLING_FUNC) { - DBGetPtrFP fp= (DBGetPtrFP) props->extra1; - ptr= fp(struct_ptr, props->struct_name, 0); - if (!ptr) return NULL; - } - - switch(props->type) { - case DBP_TYPE_CHA: - val= *((char *)ptr); - if (props->handling==DBP_HANDLING_NENM) - return named_enum_get(val, props->extra1); - else - return PyInt_FromLong(val); - case DBP_TYPE_SHO: - val= *((short *)ptr); - if (props->handling==DBP_HANDLING_NENM) - return named_enum_get(val, props->extra1); - else - return PyInt_FromLong(val); - case DBP_TYPE_INT: - val= *((int *)ptr); - if (props->handling==DBP_HANDLING_NENM) - return named_enum_get(val, props->extra1); - else - return PyInt_FromLong(val); - case DBP_TYPE_FLO: - return PyFloat_FromDouble ( *((float *)ptr) ); - case DBP_TYPE_VEC: - return newVectorObject ( ((float *)ptr), (int) props->min ); - case DBP_TYPE_FUN: - conv_fp= (DBPtrToObFP) props->extra2; - return conv_fp( ptr ); - default: - PyErr_SetString(PyExc_AttributeError, "Internal error, Unknown prop type"); - return NULL; - } - } - - props++; - } - - PyErr_SetString(PyExc_AttributeError, name); - return NULL; -} - -int datablock_setattr(DataBlockProperty *props, char *structname, char *name, void *struct_ptr, PyObject *setto) { - - while (props->public_name) { - if (STREQ(props->public_name, name)) { - void *ptr = NULL; - int type; - DBSetPtrFP conv_fp; - int clamp= props->min!=props->max; - - int enum_val= -1; - char cha_data; - short sho_data; - int int_data; - float flo_data; - - type= props->stype; - if (type==DBP_TYPE_NON) type= props->type; - - if (props->handling==DBP_HANDLING_NONE) { - ptr= get_db_ptr(props, structname, struct_ptr); - if (!ptr) return 0; - - } else if (props->handling==DBP_HANDLING_FUNC) { - if (type!=DBP_TYPE_FUN) { - DBGetPtrFP fp= (DBGetPtrFP) props->extra1; - ptr= fp(struct_ptr, props->struct_name, 1); - if (!ptr) return 0; - } - } else if (props->handling==DBP_HANDLING_NENM) { - char *str; - if (!PyArg_Parse(setto, "s", &str)) return -1; - - ptr= get_db_ptr(props, structname, struct_ptr); - if (!ptr) return 0; - - enum_val= named_enum_set(str, props->extra1); - if (enum_val==-1) - return py_err_ret_int(PyExc_AttributeError, "invalid setting for field"); - } - - switch(type) { - case DBP_TYPE_CHA: - if (enum_val==-1) { - if (!PyArg_Parse(setto, "b", &cha_data)) return -1; - } else cha_data= (char) enum_val; - - if (clamp) { - CLAMP(cha_data, (char) props->min, (char) props->max); - } - *((char *)ptr)= cha_data; - return 0; - case DBP_TYPE_SHO: - if (enum_val==-1) { - if (!PyArg_Parse(setto, "h", &sho_data)) return -1; - } else sho_data= (short) enum_val; - - if (clamp) { - CLAMP(sho_data, (short) props->min, (short) props->max); - } - *((short *)ptr)= sho_data; - return 0; - case DBP_TYPE_INT: - if (enum_val==-1) { - if (!PyArg_Parse(setto, "i", &int_data)) return -1; - } else int_data= (int) enum_val; - - if (clamp) { - CLAMP(int_data, (int) props->min, (int) props->max); - } - *((int *)ptr)= int_data; - return 0; - case DBP_TYPE_FLO: - if (!PyArg_Parse(setto, "f", &flo_data)) return -1; - if (clamp) { - CLAMP(flo_data, (float) props->min, (float) props->max); - } - *((float *)ptr)= flo_data; - return 0; - case DBP_TYPE_VEC: - /* this is very dangerous!! TYPE_VEC also can contain non floats; see - * ipo curve attribute h1t, etc. */ - if (props->min == 3.0 ) { // vector triple - return BPY_parsefloatvector(setto, (float *) ptr, 3); - } else { - return py_err_ret_int(PyExc_AttributeError, "cannot directly assign, use slice assignment instead"); - } - return 0; - - case DBP_TYPE_FUN: - conv_fp= (DBSetPtrFP) props->extra3; - if (conv_fp) - return conv_fp( struct_ptr, props->struct_name, setto ); - else - return py_err_ret_int(PyExc_AttributeError, "cannot directly assign to item"); - default: - PyErr_SetString(PyExc_AttributeError, "Internal error, Unknown prop type"); - return -1; - } - } - - props++; - } - - PyErr_SetString(PyExc_AttributeError, name); - return -1; -} - -PyObject *datablock_assignIpo(DataBlock *block, DataBlock *ipoblock) -{ - Ipo **ipoptr; - Ipo *ipo; - - if (!DataBlock_isType(ipoblock, ID_IP)) { - PyErr_SetString(PyExc_TypeError, "expects Ipo object"); - return 0; - } - - ipo = PYBLOCK_AS_IPO(ipoblock); - - if (DataBlock_type(block) != ipo->blocktype) { - PyErr_SetString(PyExc_TypeError, "Ipo type does not match object type!"); - return 0; - } - - ipoptr = get_db_ptr(block->properties, "ipo", block->data); - if (!ipoptr) { - PyErr_SetString(PyExc_RuntimeError, "Object does not have an ipo!"); - return 0; - } - - *ipoptr = ipo; - Py_INCREF(Py_None); - return Py_None; -} - -/* deallocates a Python Datablock object */ -void DataBlock_dealloc(DataBlock *self) -{ -#ifdef REF_USERCOUNT - BOB_XDECUSER(DATABLOCK_ID(self)); // XXX abuse for ref count -#endif - PyMem_DEL(self); -} - -PyObject *DataBlock_repr(DataBlock *self) -{ - static char s[256]; - if (self->data) - sprintf (s, "[%.32s %.32s]", self->type, getIDName((ID*)self->data)); - else - sprintf (s, "[%.32s %.32s]", self->type, "<deleted>"); - return Py_BuildValue("s", s); -} - -/* ************************************************************************* */ -/* datablock linking */ - -/** Link data to Object */ - -static PyObject *link_Data_toObject(DataBlock *objectblk, DataBlock *datablk) -{ - Object *object = PYBLOCK_AS_OBJECT(objectblk); - - void *data = datablk->data; - if (!object_linkdata(object, data)) - { - PyErr_SetString(PyExc_TypeError, - "Object type different from Data type or linking for this type\ - not supported"); - return NULL; - } - Py_INCREF(Py_None); - return Py_None; -} - - -#ifdef USE_NMESH -/** Special function to link NMesh data to an Object */ -static PyObject *link_NMesh_toObject(DataBlock *objectblk, NMesh *nmesh) -{ - int retval; - Mesh *mesh = nmesh->mesh; - Object *obj = PYBLOCK_AS_OBJECT(objectblk); - - // if mesh was not created yet (mesh == 0), then do so: - if (!mesh) { - mesh = Mesh_fromNMesh(nmesh); // create and convert data - nmesh->mesh = mesh; - nmesh_updateMaterials(nmesh); - } - - retval = object_linkdata(obj, mesh); - if (!retval) { - PyErr_SetString(PyExc_RuntimeError, "failed to link NMesh data"); - if (!mesh) - printf("mesh data was null\n"); // XXX - return NULL; - } - synchronizeMaterialLists(obj, obj->data); - return Py_BuildValue("i", retval); -} - -#endif - -/** This is the generic function for linking objects with each other. - * It can be called on any DataBlock, as long as this makes sense. - * Example: - * - * from Blender import Object, Scene, NMesh - * ob = Object.get("Plane") - * scene = Scene.get("2") - * ob.link(scene) - * - * or - * - * nmesh = NMesh.GetRaw('Mesh') - * ob.link(nmesh) # instanciate mesh - * - */ - -static char DataBlock_link_doc[]= -"(object) - Links 'self' with the specified object.\n\ -Only the following object types can be linked to each other:\n\ - Scene -> Object\n\ - Object -> Data (Mesh, Curve, etc.)\n\ - Object -> Materials: [Material1, Material2, ...]\n\ -\n\ -The order of linking does not matter, i.e. the following both expressions\n\ -are valid:\n\ -\n\ - scene.link(object)\n\ -\n\ - object.link(scene)\n\ -"; - -PyObject *DataBlock_link(PyObject *self, PyObject *args) -{ - DataBlock *blockA= (DataBlock*) self; - PyObject *with; - DataBlock *blockB; - -#ifdef USE_NMESH - BPY_TRY(PyArg_ParseTuple(args, "O", &with)); - - blockB = (DataBlock *) with; -#else - BPY_TRY(PyArg_ParseTuple(args, "O!", &DataBlock_Type, &blockB)); -#endif - - switch (DataBlock_type(blockA)) { - case ID_OB: - // NMesh is no datablock object, so needs special treatment: -#ifdef USE_NMESH - if (NMesh_Check(with)) { - return link_NMesh_toObject(blockA, (NMesh *) with); - } -#endif - if (!DataBlock_Check(blockB)) { - PyErr_SetString(PyExc_TypeError, "Argument must be a DataBlock object!"); - return NULL; - } - return link_Data_toObject(blockA, blockB); - - default: - PyErr_SetString(PyExc_TypeError, "FATAL: implementation error, illegal link method"); - return NULL; - } -} - -/* unlinking currently disabled, but might me needed later - for other object types... - -static char DataBlock_unlink_doc[]= -"(object) - unlinks 'self' from the specified object.\n\ -See documentation for link() for valid object types."; - -static PyObject *DataBlock_unlink(PyObject *self, PyObject *args) -{ - DataBlock *blockA= (DataBlock*) self; - DataBlock *blockB; - - BPY_TRY(PyArg_ParseTuple(args, "O!", &DataBlock_Type, &blockB)); - switch (DataBlock_type(blockA)) { - case ID_SCE: - switch(DataBlock_type(blockB)) { - case ID_OB: - return unlink_Object_fromScene(blockA, blockB); - default: - PyErr_SetString(PyExc_TypeError, "Scene unlink: invalid Object type"); - return NULL; - } - default: - PyErr_SetString(PyExc_TypeError, "cannot unlink: invalid object type"); - return NULL; - - } - -} -*/ - -/** These are the methods common to each datablock */ - -static struct PyMethodDef commonDataBlock_methods[] = { - {"link", DataBlock_link, METH_VARARGS, DataBlock_link_doc}, -// {"unlink", DataBlock_unlink, METH_VARARGS, DataBlock_unlink_doc}, - {NULL} -}; - -PyObject *DataBlock_getattr(PyObject *self, char *name) { - DataBlock *block= (DataBlock*) self; - PyObject *ret = NULL; - CHECK_VALIDDATA(block, "block was deleted!") - - // Check for common attributes: - if (STREQ(name, "name")) - return PyString_FromString((((ID*)block->data)->name)+2); - else if (STREQ(name, "block_type")) - return PyString_FromString(block->type); - else if (STREQ(name, "users")) - return PyInt_FromLong(((ID*)block->data)->us); - - // - // the following datablock types have methods: - switch (DataBlock_type(block)) { - case ID_OB: - ret = Py_FindMethod(Object_methods, self, name); - break; - case ID_IP: - ret = Py_FindMethod(Ipo_methods, self, name); - break; - case ID_CA: - ret = Py_FindMethod(Camera_methods, self, name); - break; - case ID_MA: - ret = Py_FindMethod(Material_methods, self, name); - break; - case ID_LA: - ret = Py_FindMethod(Lamp_methods, self, name); - break; - case ID_TXT: - ret = Py_FindMethod(Text_methods, self, name); - break; - } - if (ret) return ret; - PyErr_Clear(); // no method found, clear error - - // try common datablock methods - ret = Py_FindMethod(commonDataBlock_methods, (PyObject*)self, name); - if (ret) return ret; - - PyErr_Clear(); - - // try attributes from property list - ret = datablock_getattr(block->properties, block->type, name, block->data); - return ret; -} - -int DataBlock_setattr(PyObject *self, char *name, PyObject *ob) { - DataBlock *block= (DataBlock*) self; - - CHECK_VALIDDATA(block, "block was deleted!") - - if (STREQ(name, "name")) { - if (!PyArg_Parse(ob, "s", &name)) return -1; - - new_id(block->type_list, (ID*)block->data, name); - - return 0; - } - return datablock_setattr(block->properties, block->type, name, block->data, ob); -} - - -PyTypeObject DataBlock_Type = { - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "Block", /*tp_name*/ - sizeof(DataBlock), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor) DataBlock_dealloc, /*tp_dealloc*/ - (printfunc) 0, /*tp_print*/ - (getattrfunc) DataBlock_getattr, /*tp_getattr*/ - (setattrfunc) DataBlock_setattr, /*tp_setattr*/ - (cmpfunc) 0, /*tp_compare*/ - (reprfunc) DataBlock_repr, /*tp_repr*/ -}; - -/**************************************************************************/ - -/**********************/ -/* Texture Datablocks */ -/* -DATABLOCK_GET(Texturemodule, texture, getTextureList()) - -static struct PyMethodDef Texture_methods[] = { - {"Get", Texture_Get, 1, Texture_Get_doc}, - {NULL, NULL} -}; -*/ - - - -/* ---------------------------------------------------------------------- */ - -int DataBlock_type(DataBlock *block) -{ - return (GET_ID_TYPE((ID *) block->data)); -} - -int ObjectDataIDType(DataBlock *block) -{ - Object *ob; - if (!DataBlock_isType(block, ID_OB)) - return -1; - - ob = (Object *) block->data; - return GET_ID_TYPE((ID *) ob->data); -} - -int DataBlock_isType(DataBlock *block, int type) -{ - ID *id; - - if (!DataBlock_Check(block)) return 0; - id= (ID *) block->data; - return (GET_ID_TYPE(id))==type; -} - -/** This function creates a Python datablock descriptor object from - * the specified data pointer. This pointer must point to a structure - * with a valid ID header. - */ - -PyObject *DataBlock_fromData(void *data) { - DataBlock *newb; - ID *id= (ID *) data; - int idn; - - if (!data) return BPY_incr_ret(Py_None); - - idn = GET_ID_TYPE(id); - - if (idn==ID_OB) { - newb= PyObject_NEW(DataBlock, &DataBlock_Type); - newb->type= "Object"; - newb->type_list= getObjectList(); - newb->properties= Object_Properties; - - } else if (idn==ID_ME) { -#ifdef USE_NMESH - return newNMesh(data); -#else - newb= PyObject_NEW(DataBlock, &DataBlock_Type); - newb->type= "Mesh"; - newb->type_list= getMeshList(); - newb->properties= Mesh_Properties; -#endif - -// } else if (idn==ID_CU) { - /* Special case, should be fixed - * by proper high-level NURBS access. - * - * Later. - */ - -// return newNCurveObject(data); - - } else if (idn==ID_LA) { - newb= PyObject_NEW(DataBlock, &DataBlock_Type); - newb->type= "Lamp"; - newb->type_list= getLampList(); - newb->properties= Lamp_Properties; - - } else if (idn==ID_CA) { - newb= PyObject_NEW(DataBlock, &DataBlock_Type); - newb->type= "Camera"; - newb->type_list= getCameraList(); - newb->properties= Camera_Properties; - - } else if (idn==ID_MA) { - newb= PyObject_NEW(DataBlock, &DataBlock_Type); - newb->type= "Material"; - newb->type_list= getMaterialList(); - newb->properties= Material_Properties; - - } else if (idn==ID_WO) { - newb= PyObject_NEW(DataBlock, &DataBlock_Type); - newb->type= "World"; - newb->type_list= getWorldList(); - newb->properties= World_Properties; - - } else if (idn==ID_IP) { - newb= PyObject_NEW(DataBlock, &DataBlock_Type); - newb->type= "Ipo"; - newb->type_list= getIpoList(); - newb->properties= Ipo_Properties; - -#ifdef EXPERIMENTAL - } else if (idn==ID_TE) { - newb= PyObject_NEW(DataBlock, &DataBlock_Type); - newb->type= "Tex"; - newb->type_list= getTextureList(); - newb->properties= Texture_Properties; -#endif - - } else if (idn==ID_IM) { - newb= PyObject_NEW(DataBlock, &DataBlock_Type); - newb->type= "Image"; - newb->type_list= getImageList(); - newb->properties= Image_Properties; - - } else if (idn==ID_TXT) { - newb= PyObject_NEW(DataBlock, &DataBlock_Type); - newb->type= "Text"; - newb->type_list= getTextList(); - newb->properties= Text_Properties; - } else return BPY_err_ret_ob(PyExc_SystemError, "unable to create Block for data"); - - newb->data= data; -#ifdef REF_USERCOUNT - BOB_INCUSER(id); // XXX abuse for refcount -#endif - - return (PyObject *) newb; -} - -PyObject *get_DataBlock_func(void **ptr) { - ID *id= (ID*) *ptr; - return DataBlock_fromData(id); -} - -/* ---------------------------------------------------------------------- */ -/* INIT ROUTINE */ - - -void init_types(PyObject *dict) -{ - PyObject *tmod, *tdict; - - tmod= Py_InitModule("Blender.Types", Null_methods); - PyDict_SetItemString(dict, "Types", tmod); - - tdict= PyModule_GetDict(tmod); - - PyDict_SetItemString(tdict, "IpoCurve", (PyObject *)&PyIpoCurve_Type); - PyDict_SetItemString(tdict, "BezTriple", (PyObject *)&PyBezTriple_Type); - - PyDict_SetItemString(tdict, "ButtonType", (PyObject *)&Button_Type); - PyDict_SetItemString(tdict, "BufferType", (PyObject *)&Buffer_Type); - PyDict_SetItemString(tdict, "NMeshType", (PyObject *)&NMesh_Type); - PyDict_SetItemString(tdict, "NMFaceType", (PyObject *)&NMFace_Type); - PyDict_SetItemString(tdict, "NMVertType", (PyObject *)&NMVert_Type); - PyDict_SetItemString(tdict, "NMColType", (PyObject *)&NMCol_Type); - - PyDict_SetItemString(tdict, "BlockType", (PyObject *)&DataBlock_Type); - - /* Setup external types */ - PyDict_SetItemString(tdict, "VectorType", (PyObject *)&Vector_Type); - PyDict_SetItemString(tdict, "MatrixType", (PyObject *)&Matrix_Type); -} - -#undef BPY_ADDCONST -#define BPY_ADDCONST(dict, name) insertConst(dict, #name, PyInt_FromLong(LA_##name)) - -PyObject *initLamp(void) -{ - PyObject *mod, *dict, *d; - - mod= Py_InitModule(MODNAME(BLENDERMODULE) ".Lamp", Lampmodule_methods); - dict= PyModule_GetDict(mod); - d = ConstObject_New(); - PyDict_SetItemString(dict, "Types", d); - - /* type */ - BPY_ADDCONST(d, LOCAL); - BPY_ADDCONST(d, SUN); - BPY_ADDCONST(d, SPOT); - BPY_ADDCONST(d, HEMI); - - d = ConstObject_New(); - PyDict_SetItemString(dict, "Modes", d); - - /* mode */ - BPY_ADDCONST(d, SHAD); - BPY_ADDCONST(d, HALO); - BPY_ADDCONST(d, LAYER); - BPY_ADDCONST(d, QUAD); - BPY_ADDCONST(d, NEG); - BPY_ADDCONST(d, ONLYSHADOW); - BPY_ADDCONST(d, SPHERE); - BPY_ADDCONST(d, SQUARE); - BPY_ADDCONST(d, TEXTURE); - BPY_ADDCONST(d, OSATEX); - BPY_ADDCONST(d, DEEP_SHADOW); - - return mod; -} - -PyObject *initMaterial(void) -{ - PyObject *mod, *dict, *d; - - mod= Py_InitModule(MODNAME(BLENDERMODULE) ".Material", - Materialmodule_methods); - dict= PyModule_GetDict(mod); - d = ConstObject_New(); - PyDict_SetItemString(dict, "Modes", d); - - /* MATERIAL MODES - * ...some of these have really cryptic defines :-) - * We try to match them to the GUI descriptions... */ - -#undef BPY_ADDCONST -#define BPY_ADDCONST(dict, name) \ - insertConst(dict, #name, PyInt_FromLong(MA_##name)) - - insertConst(d, "TRACEABLE", PyInt_FromLong(MA_TRACEBLE)); - BPY_ADDCONST(d, SHADOW); - insertConst(d, "SHADELESS", PyInt_FromLong(MA_SHLESS)); - BPY_ADDCONST(d, WIRE); - insertConst(d, "VCOL_LIGHT", PyInt_FromLong(MA_VERTEXCOL)); - BPY_ADDCONST(d, HALO); - insertConst(d, "ZTRANSP", PyInt_FromLong(MA_ZTRA)); - insertConst(d, "VCOL_PAINT", PyInt_FromLong(MA_VERTEXCOLP)); - insertConst(d, "ZINVERT", PyInt_FromLong(MA_ZINV)); - BPY_ADDCONST(d, ONLYSHADOW); - BPY_ADDCONST(d, STAR); - insertConst(d, "TEXFACE", PyInt_FromLong(MA_FACETEXTURE)); - BPY_ADDCONST(d, NOMIST); - - /* HALO MODES */ - d = ConstObject_New(); - PyDict_SetItemString(dict, "HaloModes", d); - -#undef BPY_ADDCONST -#define BPY_ADDCONST(dict, name) \ - insertConst(dict, #name, PyInt_FromLong(MA_HALO_##name)) - - BPY_ADDCONST(d, RINGS); - BPY_ADDCONST(d, LINES); - insertConst(d, "TEX", PyInt_FromLong(MA_HALOTEX)); - insertConst(d, "PUNO", PyInt_FromLong(MA_HALOPUNO)); - BPY_ADDCONST(d, SHADE); - BPY_ADDCONST(d, FLARE); - - return mod; -} - -void init_Datablockmodules(PyObject *dict) { -#define MODLOAD(name) PyDict_SetItemString(dict, #name, Py_InitModule(MODNAME(BLENDERMODULE) "." #name, name##module_methods)) - - DataBlock_Type.ob_type = &PyType_Type; - PyIpoCurve_Type.ob_type= &PyType_Type; - PyBezTriple_Type.ob_type= &PyType_Type; - - PyDict_SetItemString(dict, "Object", initObject()); - PyDict_SetItemString(dict, "Lamp", initLamp()); - PyDict_SetItemString(dict, "Material", initMaterial()); - PyDict_SetItemString(dict, "Ipo", initIpo()); - PyDict_SetItemString(dict, "Scene", initScene()); - MODLOAD(Text); -// MODLOAD(Mesh); - MODLOAD(Camera); - MODLOAD(World); - MODLOAD(Image); -/* MODLOAD(Texture); */ -} |