Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/bpython/intern/opy_datablock.c')
-rw-r--r--source/blender/bpython/intern/opy_datablock.c1299
1 files changed, 1299 insertions, 0 deletions
diff --git a/source/blender/bpython/intern/opy_datablock.c b/source/blender/bpython/intern/opy_datablock.c
new file mode 100644
index 00000000000..6804c834897
--- /dev/null
+++ b/source/blender/bpython/intern/opy_datablock.c
@@ -0,0 +1,1299 @@
+/* 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 */
+
+
+/* ---------------------------------------------------------------------- */
+
+/*********************/
+/* 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); */
+}