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')
-rw-r--r--source/blender/bpython/Makefile37
-rw-r--r--source/blender/bpython/include/BPY_extern.h60
-rw-r--r--source/blender/bpython/include/BPY_objtypes.h38
-rw-r--r--source/blender/bpython/intern/BPY_constobject.c183
-rw-r--r--source/blender/bpython/intern/BPY_constobject.h40
-rw-r--r--source/blender/bpython/intern/BPY_csg.c239
-rw-r--r--source/blender/bpython/intern/BPY_csg.h35
-rw-r--r--source/blender/bpython/intern/BPY_image.c103
-rw-r--r--source/blender/bpython/intern/BPY_ipo.c717
-rw-r--r--source/blender/bpython/intern/BPY_links.c96
-rw-r--r--source/blender/bpython/intern/BPY_listbase_macro.h62
-rw-r--r--source/blender/bpython/intern/BPY_macros.h268
-rw-r--r--source/blender/bpython/intern/BPY_main.c672
-rw-r--r--source/blender/bpython/intern/BPY_main.h86
-rw-r--r--source/blender/bpython/intern/BPY_modules.h47
-rw-r--r--source/blender/bpython/intern/BPY_object.c499
-rw-r--r--source/blender/bpython/intern/BPY_scene.c506
-rw-r--r--source/blender/bpython/intern/BPY_text.c295
-rw-r--r--source/blender/bpython/intern/BPY_tools.c106
-rw-r--r--source/blender/bpython/intern/BPY_tools.h37
-rw-r--r--source/blender/bpython/intern/BPY_types.h39
-rw-r--r--source/blender/bpython/intern/BPY_window.h33
-rw-r--r--source/blender/bpython/intern/Makefile75
-rw-r--r--source/blender/bpython/intern/README22
-rw-r--r--source/blender/bpython/intern/api.h87
-rw-r--r--source/blender/bpython/intern/b_import.c191
-rw-r--r--source/blender/bpython/intern/b_import.h35
-rw-r--r--source/blender/bpython/intern/b_interface.c753
-rw-r--r--source/blender/bpython/intern/b_interface.h184
-rw-r--r--source/blender/bpython/intern/opy_blender.c342
-rw-r--r--source/blender/bpython/intern/opy_datablock.c1299
-rw-r--r--source/blender/bpython/intern/opy_datablock.h193
-rw-r--r--source/blender/bpython/intern/opy_draw.c2679
-rw-r--r--source/blender/bpython/intern/opy_matrix.c173
-rw-r--r--source/blender/bpython/intern/opy_nmesh.c1716
-rw-r--r--source/blender/bpython/intern/opy_nmesh.h93
-rw-r--r--source/blender/bpython/intern/opy_vector.c241
-rw-r--r--source/blender/bpython/intern/opy_vector.h63
-rw-r--r--source/blender/bpython/intern/opy_window.c194
39 files changed, 12538 insertions, 0 deletions
diff --git a/source/blender/bpython/Makefile b/source/blender/bpython/Makefile
new file mode 100644
index 00000000000..ef58948bd88
--- /dev/null
+++ b/source/blender/bpython/Makefile
@@ -0,0 +1,37 @@
+#
+# $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 *****
+#
+# Bounces make to subdirectories.
+
+SOURCEDIR = source/blender/bpython
+DIRS = intern
+
+include nan_subdirs.mk
diff --git a/source/blender/bpython/include/BPY_extern.h b/source/blender/bpython/include/BPY_extern.h
new file mode 100644
index 00000000000..8aa9a2502fc
--- /dev/null
+++ b/source/blender/bpython/include/BPY_extern.h
@@ -0,0 +1,60 @@
+/**
+ * $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 *****
+ */
+struct Text;
+struct ID;
+struct ScriptLink;
+struct ListBase;
+struct SpaceText;
+struct _object; // forward declaration for PyObject !
+
+
+void BPY_start_python(void);
+void BPY_end_python(void);
+int BPY_Err_getLinenumber(void);
+const char *BPY_Err_getFilename(void);
+void BPY_Err_Handle(struct Text *text);
+struct _object *BPY_txt_do_python(struct SpaceText* st);
+void BPY_free_compiled_text(struct Text* text);
+void BPY_clear_bad_scriptlink(struct ID *id, struct Text *byebye);
+void BPY_clear_bad_scriptlinks(struct Text *byebye);
+void BPY_clear_bad_scriptlist(struct ListBase *, struct Text *byebye);
+void BPY_do_all_scripts(short event);
+void BPY_do_pyscript(struct ID *id, short event);
+void BPY_free_scriptlink(struct ScriptLink *slink);
+void BPY_copy_scriptlink(struct ScriptLink *scriptlink);
+
+/* format importer hook */
+int BPY_call_importloader(char *name);
+
+int BPY_spacetext_is_pywin(struct SpaceText *st);
+void BPY_spacetext_do_pywin_draw(struct SpaceText *st);
+void BPY_spacetext_do_pywin_event(struct SpaceText *st, unsigned short event, short val);
diff --git a/source/blender/bpython/include/BPY_objtypes.h b/source/blender/bpython/include/BPY_objtypes.h
new file mode 100644
index 00000000000..91cdc5ceb96
--- /dev/null
+++ b/source/blender/bpython/include/BPY_objtypes.h
@@ -0,0 +1,38 @@
+/**
+ * $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 "DNA_ID.h"
+#include "DNA_listBase.h"
+#include "DNA_mesh_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_material_types.h"
+#include "DNA_object_types.h"
+
diff --git a/source/blender/bpython/intern/BPY_constobject.c b/source/blender/bpython/intern/BPY_constobject.c
new file mode 100644
index 00000000000..9f1a6b4cc3b
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_constobject.c
@@ -0,0 +1,183 @@
+/*
+ *
+ * ***** 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 *****
+$Id$
+
+This is code to emulate a readonly Dictionary/Class object
+for storage of Constants
+
+Inserting readonly values:
+
+PyObject *constants = ConstObject_New();
+insertConst(constants, "item", PyInt_FromInt(CONSTANT));
+...
+
+
+Constant values are accessed in python by either:
+
+c = module.Const.CONSTANT
+
+ or
+
+c = module.Const['CONSTANT']
+
+*/
+
+#include "Python.h"
+#include "BPY_macros.h"
+
+#include "BPY_constobject.h"
+
+#define Const_Check(v) ((v)->ob_type == &Const_Type)
+
+
+/* ----------------------------------------------------- */
+/* Declarations for objects of type const */
+
+
+PyTypeObject Const_Type;
+
+/* PROTOS */
+
+
+
+static constobject *
+newconstobject()
+{
+ constobject *self;
+ Const_Type.ob_type = &PyType_Type;
+ self = PyObject_NEW(constobject, &Const_Type);
+ if (self == NULL)
+ return NULL;
+ self->dict = PyDict_New();
+ return self;
+}
+
+char ConstObject_doc[] = "Readonly dictionary type\n\n\
+This is used as a container for constants, which can be accessed by two ways:\n\
+\n\
+ c = <ConstObject>.<attribute>\n\
+\n\
+or\n\
+ c = <ConstObject>['<attribute>']";
+
+PyObject *ConstObject_New(void)
+{
+ return (PyObject *) newconstobject();
+}
+
+PyObject *const_repr(constobject *self)
+{
+ PyObject *repr;
+ repr = PyObject_Repr(self->dict);
+ return repr;
+}
+
+static void const_dealloc(PyObject *self) {
+ Py_DECREF(((constobject *)self)->dict);
+ PyMem_DEL(self);
+}
+static PyObject *
+const_getattr(constobject *self, char *name)
+{
+ PyObject *item;
+ if (STREQ(name, "__doc__")) {
+ return PyString_FromString(ConstObject_doc);
+ }
+ if (STREQ(name, "__members__")) {
+ return PyDict_Keys(self->dict);
+ }
+ item = PyDict_GetItemString(self->dict, name); /* borrowed ref ! */
+ if (item)
+ Py_INCREF(item);
+ if (!item) {
+ PyErr_SetString(PyExc_AttributeError, name);
+ }
+ return item;
+}
+
+/* inserts a constant with name into the dictionary self */
+void insertConst(PyObject *self, char *name, PyObject *cnst)
+{
+ PyDict_SetItemString(((constobject *)self)->dict, name, cnst);
+}
+
+
+/* Code to access const objects as mappings */
+
+static int
+const_length(constobject *self)
+{
+ return 0;
+}
+
+static PyObject *
+const_subscript(constobject *self, PyObject *key)
+{
+ PyObject *item;
+ item = PyDict_GetItem(self->dict, key);
+ if (item)
+ Py_INCREF(item);
+ return item;
+}
+
+static int
+const_ass_sub(constobject *self, PyObject *v, PyObject *w)
+{
+ /* no write access */
+ return 0;
+}
+
+static PyMappingMethods const_as_mapping = {
+ (inquiry)const_length, /*mp_length*/
+ (binaryfunc)const_subscript, /*mp_subscript*/
+ (objobjargproc)const_ass_sub, /*mp_ass_subscript*/
+};
+
+/* -------------------------------------------------------- */
+
+PyTypeObject Const_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "const", /*tp_name*/
+ sizeof(constobject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor) const_dealloc, /*tp_dealloc*/
+ (printfunc) 0, /*tp_print*/
+ (getattrfunc) const_getattr, /*tp_getattr*/
+ (setattrfunc) 0, /*tp_setattr*/
+ (cmpfunc) 0, /*tp_compare*/
+ (reprfunc) const_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ &const_as_mapping, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+};
+
diff --git a/source/blender/bpython/intern/BPY_constobject.h b/source/blender/bpython/intern/BPY_constobject.h
new file mode 100644
index 00000000000..b75ba202765
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_constobject.h
@@ -0,0 +1,40 @@
+/**
+ * $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 *****
+ */
+typedef struct {
+ PyObject_HEAD
+ PyObject *dict;
+
+} constobject;
+
+PyObject *ConstObject_New(void);
+void insertConst(PyObject *self, char *name, PyObject *cnst);
+
diff --git a/source/blender/bpython/intern/BPY_csg.c b/source/blender/bpython/intern/BPY_csg.c
new file mode 100644
index 00000000000..7237a843428
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_csg.c
@@ -0,0 +1,239 @@
+
+/** CSG wrapper module
+ *
+ * ***** 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 *****
+ * $Id$
+ */
+
+// TODO
+
+
+#include "Python.h"
+
+#include "BPY_csg.h"
+
+#include "BKE_booleanops_mesh.h"
+#include "BKE_booleanops.h"
+#include "MEM_guardedalloc.h"
+
+#include "b_interface.h"
+
+#ifdef DEBUG
+ #define CSG_DEBUG(str) \
+ { printf str; }
+#else
+ #define CSG_DEBUG(str) \
+ {}
+#endif
+
+
+///////////////////////////////////////////////////////////////
+// CSG python object struct
+
+
+typedef struct _CSGMesh {
+ PyObject_VAR_HEAD
+ CSG_MeshDescriptor *imesh;
+} PyCSGMesh;
+
+// PROTOS
+
+static PyObject *newPyCSGMesh(CSG_MeshDescriptor *imesh);
+
+static void CSGMesh_dealloc(PyObject *self);
+static PyObject *CSGMesh_getattr(PyObject *self, char *attr);
+
+
+static char CSGMesh_Type_doc[] = "CSG mesh type";
+
+static PyTypeObject PyCSGMesh_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "CSGMesh", /*tp_name*/
+ sizeof(PyCSGMesh), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor) CSGMesh_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)CSGMesh_getattr, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc)0, /*tp_compare*/
+ (reprfunc)0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+ (ternaryfunc)0, /*tp_call*/
+ (reprfunc)0, /*tp_str*/
+
+ /* Space for future expansion */
+ 0L,0L,0L,0L,
+ CSGMesh_Type_doc /* Documentation string */
+};
+
+///////////////////////////////////////////////////////////////
+// CSG object methods
+
+
+static PyObject *CSGMesh_add(PyObject *self, PyObject *args)
+{
+ CSG_MeshDescriptor *new_imesh =
+ (CSG_MeshDescriptor *) MEM_mallocN(sizeof(CSG_MeshDescriptor),
+ "CSG_IMesh");
+
+ PyCSGMesh *c2;
+ int success = 0;
+
+ PyCSGMesh *c1 = (PyCSGMesh *) self;
+ if (!PyArg_ParseTuple(args, "O!", &PyCSGMesh_Type, &c2)) return NULL;
+
+ success = CSG_PerformOp(c1->imesh, c2->imesh, 2, new_imesh);
+
+ if (!success) {
+ PyErr_SetString(PyExc_RuntimeError, "Sorry. Didn't work");
+ return NULL; // exception
+ }
+ return newPyCSGMesh(new_imesh);
+}
+
+
+static PyMethodDef CSGMesh_methods[] = {
+ {"union", CSGMesh_add, METH_VARARGS, 0 },
+ // add more methods here
+ {NULL, NULL, 0, NULL}
+};
+
+
+static void CSGMesh_dealloc(PyObject *self)
+{
+ CSG_MeshDescriptor *imesh = ((PyCSGMesh *) self)->imesh;
+ CSG_DEBUG(("object was destroyed\n"));
+ // TODO: delete (free) struct ptr
+ CSG_DestroyMeshDescriptor(imesh);
+ MEM_freeN(imesh);
+ PyMem_DEL(self);
+}
+
+static PyObject *CSGMesh_getattr(PyObject *self, char *attr)
+{
+ return Py_FindMethod(CSGMesh_methods, (PyObject *) self, attr);
+}
+///////////////////////////////////////////////////////////////
+// CSG module methods
+
+static PyObject *newPyCSGMesh(CSG_MeshDescriptor *imesh)
+{
+ PyCSGMesh *c = PyObject_NEW(PyCSGMesh, &PyCSGMesh_Type);
+ CSG_DEBUG(("object was created\n"));
+ c->imesh = imesh;
+ // add init bla here
+ return (PyObject *) c;
+}
+
+static PyObject *CSGmodule_CSGMesh(PyObject *self, PyObject *args)
+{
+ char *name;
+
+ Object *obj;
+ CSG_MeshDescriptor *new_imesh;
+
+ if (!PyArg_ParseTuple(args, "s", &name)) return NULL;
+ new_imesh = (CSG_MeshDescriptor *) MEM_mallocN(
+ sizeof(CSG_MeshDescriptor),
+ "CSG_IMesh");
+
+ // get object by name, return its mesh data
+ // and do the conversion
+ // CSG_LoadBlenderMesh(name, new_imesh);
+
+ obj = (Object *) getFromList(getObjectList(), name);
+
+ if (!obj) {
+ PyErr_SetString(PyExc_AttributeError,
+ "requested Object does not exist");
+ return NULL;
+ }
+
+ if (obj->type != OB_MESH) {
+ PyErr_SetString(PyExc_TypeError, "Mesh object expected");
+ return NULL;
+ }
+
+ if (!CSG_LoadBlenderMesh(obj, new_imesh)) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "FATAL: Could not acquire mesh data");
+ return NULL;
+ }
+ return newPyCSGMesh(new_imesh);
+}
+
+static PyObject *CSGmodule_toBlenderMeshObject(PyObject *self,
+ PyObject *args)
+{
+ Object *new_object;
+ PyCSGMesh *pmesh;
+ CSG_MeshDescriptor *c;
+
+ float identity[4][4] = { {1.0, 0.0, 0.0, 0.0},
+ {0.0, 1.0, 0.0, 0.0},
+ {0.0, 0.0, 1.0, 0.0},
+ {0.0, 0.0, 0.0, 1.0}};
+
+
+ if (!PyArg_ParseTuple(args, "O!", &PyCSGMesh_Type, &pmesh)) return NULL;
+ c = pmesh->imesh;
+ new_object = object_new(OB_MESH);
+
+ if (!PyArg_ParseTuple(self, "")) return NULL;
+ // TODO: blender mesh conversion
+ ConvertCSGDescriptorsToMeshObject(new_object, &c->m_descriptor,
+ &c->m_face_iterator,
+ &c->m_vertex_iterator,
+ identity);
+
+ // return resulting object
+ return DataBlock_fromData(new_object);
+}
+
+static PyMethodDef CSGmodule_methods[] = {
+ {"CSGMesh", CSGmodule_CSGMesh , METH_VARARGS, 0 },
+ {"toObject", CSGmodule_toBlenderMeshObject, METH_VARARGS, 0 },
+ {NULL, NULL, 0, NULL}
+};
+
+// MODULE INITIALIZATION
+
+void initcsg()
+{
+ PyObject *mod;
+ PyCSGMesh_Type.ob_type = &PyType_Type;
+ mod = Py_InitModule("csg", CSGmodule_methods);
+
+}
+
diff --git a/source/blender/bpython/intern/BPY_csg.h b/source/blender/bpython/intern/BPY_csg.h
new file mode 100644
index 00000000000..8b4a829a057
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_csg.h
@@ -0,0 +1,35 @@
+/**
+ * $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 "BPY_macros.h"
+
+#include "opy_datablock.h"
+#include "b_interface.h"
diff --git a/source/blender/bpython/intern/BPY_image.c b/source/blender/bpython/intern/BPY_image.c
new file mode 100644
index 00000000000..a94abb594a7
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_image.c
@@ -0,0 +1,103 @@
+/**
+ * Image 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 *****
+ */
+
+#include "Python.h"
+#include "opy_datablock.h"
+
+#include "DNA_image_types.h"
+#include "BKE_image.h"
+
+#include "BPY_macros.h"
+#include "b_interface.h"
+
+PyObject *INITMODULE(Image)(void);
+
+/* Image_Get */
+DATABLOCK_GET(Imagemodule, image, getImageList())
+
+char Imagemodule_load_doc[] = "(filename) - return image from file 'filename' as Image object";
+
+PyObject *Imagemodule_load(PyObject *self, PyObject *args)
+{
+ char *name;
+ Image *im;
+
+ if (!PyArg_ParseTuple(args, "s", &name)) {
+ PyErr_SetString(PyExc_TypeError, "filename expected");
+ return 0;
+ }
+
+ im = add_image(name);
+ if (im) {
+ return DataBlock_fromData(im);
+ } else {
+ PyErr_SetString(PyExc_IOError, "couldn't load image");
+ return 0;
+ }
+}
+
+DataBlockProperty Image_Properties[]= {
+ {"xrep", "xrep", DBP_TYPE_SHO, 0, 1.0, 16.0},
+ {"yrep", "yrep", DBP_TYPE_SHO, 0, 1.0, 16.0},
+// {"PackedFile", "*packedfile", DBP_TYPE_FUN, 0, 0.0, 0.0, {0}, {0}, 0, 0, get_DataBlock_func},
+ {NULL}
+};
+
+#undef MethodDef
+#define MethodDef(func) _MethodDef(func, Imagemodule)
+
+struct PyMethodDef Imagemodule_methods[] = {
+ MethodDef(get),
+ MethodDef(load),
+ // for compatibility:
+ {"Load", Imagemodule_load, METH_VARARGS, Imagemodule_load_doc},
+ {NULL, NULL}
+};
+
+
+/*
+void Image_getattr(void *vdata, char *name)
+{
+}
+*/
+
+
+PyObject *INITMODULE(Image)(void)
+{
+ PyObject *mod= Py_InitModule(SUBMODULE(Image), Imagemodule_methods);
+ return mod;
+}
+
+
+
+
diff --git a/source/blender/bpython/intern/BPY_ipo.c b/source/blender/bpython/intern/BPY_ipo.c
new file mode 100644
index 00000000000..237692ca38d
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_ipo.c
@@ -0,0 +1,717 @@
+/** 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;
+}
diff --git a/source/blender/bpython/intern/BPY_links.c b/source/blender/bpython/intern/BPY_links.c
new file mode 100644
index 00000000000..e3c6458ef82
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_links.c
@@ -0,0 +1,96 @@
+/** Helper functions to handle links between Object types,
+ * Script links */
+
+/*
+ * $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 "b_interface.h"
+
+/* GLOBALS */
+
+PyObject *g_blenderdict;
+
+/* PROTOS */
+char *event_to_name(short event);
+void set_scriptlinks(ID *id, short event);
+
+#ifndef SHAREDMODULE
+PyObject *DataBlock_fromData (void *data);
+
+
+void set_scriptlinks(ID *id, short event)
+{
+ PyObject *link;
+
+ if (!g_blenderdict) // not initialized yet; this can happen at first file load
+ {
+ return;
+ }
+ if (GET_ID_TYPE(id) == ID_SCE) {
+ Py_INCREF(Py_None);
+ link = Py_None;
+ } else {
+ link = DataBlock_fromData(id);
+ }
+
+ if (!link)
+ {
+ printf ("Internal error, unable to create PyBlock for script link\n");
+ printf ("This is a bug; please report to bugs@blender.nl");
+ Py_INCREF(Py_False);
+ PyDict_SetItemString(g_blenderdict, "bylink", Py_False);
+ return;
+ } else {
+ Py_INCREF(Py_True);
+ PyDict_SetItemString(g_blenderdict, "bylink", Py_True);
+ }
+
+ PyDict_SetItemString(g_blenderdict, "link", link);
+ PyDict_SetItemString(g_blenderdict, "event", Py_BuildValue("s", event_to_name(event)));
+}
+
+/* this is just a hack-added function to release a script link reference.
+ * The scriptlink concept will be redone later */
+
+void release_scriptlinks(ID *id)
+{
+ PyObject *link;
+ if (!g_blenderdict) return; // return if Blender module was not initialized
+ link = PyDict_GetItemString(g_blenderdict, "link");
+ Py_DECREF(link);
+ Py_INCREF(Py_None);
+ PyDict_SetItemString(g_blenderdict, "link", Py_None);
+}
+
+#endif
diff --git a/source/blender/bpython/intern/BPY_listbase_macro.h b/source/blender/bpython/intern/BPY_listbase_macro.h
new file mode 100644
index 00000000000..5c5047d22d8
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_listbase_macro.h
@@ -0,0 +1,62 @@
+/**
+ $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 *****
+ These are macros to create python lists from base lists.
+*/
+
+
+
+/** example: DEFFUNC_GETLIST(text) defines a method for getting a list
+ * of text blocks */
+
+// Example: _GETLIST(name) -> get_namelist
+#define _GETLIST(x) get_##x##list
+
+// Function definition:
+// DEFFUNC_GETLIST_MAIN(name) -> get_namelist(PyObject *self, PyObject *args)
+#define DEFFUNC_GETLIST_MAIN(x) \
+ PyObject *_GETLIST(x)(PyObject *self, PyObject *args) \
+ { \
+ ID *id; \
+ PyObject *list; \
+ list = PyList_New(0); \
+ id = G.main->##x##.first; \
+ while (id) \
+ { \
+ PyList_Append(list, PyString_FromString(id->name+2)); \
+ id = id->next; \
+ } \
+ return list; \
+ } \
+
+// call the above function
+#define GETLISTFUNC(x) _GETLIST(x)
+// Prototype for the above function
+#define GETLISTPROTO(x) PyObject *_GETLIST(x)(PyObject *, PyObject *)
diff --git a/source/blender/bpython/intern/BPY_macros.h b/source/blender/bpython/intern/BPY_macros.h
new file mode 100644
index 00000000000..9f9bea4864a
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_macros.h
@@ -0,0 +1,268 @@
+
+/* bpython library macros
+ *
+ * $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 *****
+ *
+ */
+
+
+/* Hint: use gcc -E file.c to see what these macros are expanded in */
+
+#include "api.h" // temporary defines for API version
+
+#include "BPY_listbase_macro.h"
+#include "BKE_utildefines.h"
+
+/* CONSTANTS */
+
+#define IDNAME 24
+#define PATH_MAXCHAR 128
+
+/* ALIASES */
+
+#define BPY_TRY(x) {if((!(x))) return NULL;}
+#define BPY_TRY_TYPEERROR(x, str) \
+ { if(!(x)) { \
+ PyErr_SetString(PyExc_TypeError, str); \
+ return NULL; }\
+ }
+
+#define BPY_ADDCONST(dict, name) PyDict_SetItemString(dict, #name, PyInt_FromLong(name))
+#define CurrentFrame (getGlobal()->scene->r.cfra)
+#define RETURN_INC(ob) {Py_INCREF(ob); return ob; }
+
+/* Blender object internal 'reference' (user) counting */
+/* 'x' must be of type (ID *) */
+
+#ifdef DEBUG
+
+ #define BOB_USERCOUNT(x) \
+ (x)->us
+ #define BOB_DECUSER(x) \
+ printf("BOB_DECUSER: %s\n", (x)->name); \
+ (x)->us ? (x)->us--:printf("FATAL: 0--\n")
+ #define BOB_INCUSER(x) \
+ printf("BOB_INCUSER: %s\n", (x)->name); \
+ id_us_plus(x)
+ /* safe ref-inc/dec */
+ #define BOB_XDECUSER(x) \
+ if (x) { \
+ printf("BOB_XDECUSER: %s\n", (x)->name); \
+ ((x)->us ? (x)->us--:printf("FATAL: 0--\n")); \
+ }
+ #define BOB_XINCUSER(x) \
+ if (x) { \
+ printf("BOB_XINCUSER: %s\n", (x)->name); \
+ if (x) id_us_plus(x); \
+ }
+#else
+
+ #define BOB_USERCOUNT(x) \
+ (x)->us
+ #define BOB_DECUSER(x) \
+ (x)->us ? (x)->us--:printf("FATAL: 0--\n")
+ #define BOB_INCUSER(x) \
+ id_us_plus(x)
+ /* safe ref-inc/dec */
+ #define BOB_XDECUSER(x) \
+ if (x) ((x)->us ? (x)->us--:printf("FATAL: 0--\n"))
+ #define BOB_XINCUSER(x) \
+ if (x) id_us_plus(x)
+
+#endif
+
+/* WARNINGS, Verbose */
+
+#define BPY_CHECKFLAG(x) (getGlobal()->f & x)
+#define BPY_DEBUGFLAG BPY_CHECKFLAG(G_DEBUG)
+#define BPY_debug(a) if BPY_DEBUGFLAG {printf a; }
+#define BPY_warn(a) {printf a; }
+
+/* BLENDER DATABLOCK ACCESS */
+
+/* these are relicts... */
+#define GS(a) (*((short *)(a)))
+#define STREQ(str, a) ( strcmp((str), (a))==0 )
+
+/** This macro should be used to get the (short) id type of a ID datablock
+ * structure (Object, Mesh, etc.)
+ * Usage is dangerous, so use it only if you know what you're doing :-)
+ * Otherwise, use DataBlock_type() or associated functions (datablock.c)
+ */
+
+#define GET_ID_TYPE(x) (GS((x)->name))
+
+/* gets the datablock's ID pointer. be careful with its usage,
+ * - no typechecking done! */
+#define DATABLOCK_ID(x) ( (ID *) ((DataBlock *) x)->data)
+
+/** This defines the Get method plus documentation for use in a
+ * Method definition list.
+ * Example:
+ *
+ * DATABLOCK_GET(modulename, objectname, listbase.first)
+ *
+ * This function, called in Python by:
+ *
+ * modulename.Get(name)
+ *
+ * returns a Python DataBlock object for the Blender object with name
+ * 'name'. If 'name' omitted, a list of all the objects in the
+ * given list (a linked list of ID pointers) is returned
+ */
+
+
+#define DATABLOCK_GET(uname, docname, list) \
+static char uname##_get_doc[]= \
+"([name]) - Get " #docname "s from Blender\n" \
+"\n" \
+"[name] The name of the " #docname " to return\n" \
+"\n" \
+"Returns a list of all " #docname "s if name is not specified"; \
+ \
+static PyObject* uname##_get (PyObject *self, PyObject *args) { \
+ return py_find_from_list(list, args); \
+}
+
+/** This macro defines the creation of new Objects */
+
+#define DATABLOCK_NEW( modprefix, type, callfunc) \
+static char modprefix##_New_doc[] = \
+"() - returns new " #type " object"; \
+ \
+PyObject *modprefix##_New (PyObject *self, PyObject *args) \
+{ \
+ type *obj; \
+ char *name = #type; \
+ BPY_TRY(PyArg_ParseTuple(args, "|s", &name)); \
+ obj = callfunc; \
+ return DataBlock_fromData(obj); \
+} \
+
+#define DATABLOCK_ASSIGN_IPO(type, prefix) \
+static char type##_assignIpo_doc[]= \
+"(ipo) - assigns Ipo to object of type " #type ; \
+ \
+static PyObject *type##_assignIpo(PyObject *self, PyObject *args) \
+{ \
+ DataBlock *ipoblock; \
+ Ipo *ipo; \
+ type *object = PYBLOCK_AS(type, self); \
+ \
+ BPY_TRY(PyArg_ParseTuple(args, "O!", &DataBlock_Type, &ipoblock));\
+ if (!DataBlock_isType(ipoblock, ID_IP)) { \
+ PyErr_SetString(PyExc_TypeError, "expects Ipo object"); \
+ return 0; \
+ } \
+ ipo = PYBLOCK_AS_IPO(ipoblock); \
+ \
+ if (ipo->blocktype != GET_ID_TYPE((ID *) object)) { \
+ PyErr_SetString(PyExc_TypeError, \
+ "Ipo type does not match object type"); \
+ return 0; \
+ } \
+ prefix##_assignIpo(object, ipo); \
+ \
+ Py_INCREF(Py_None); \
+ return Py_None; \
+} \
+ \
+static char type##_clrIpo_doc[]= \
+"(ipo) - clears Ipo" ; \
+ \
+static PyObject *type##_clrIpo(PyObject *self, PyObject *args) \
+{ \
+ type *object = PYBLOCK_AS(type, self); \
+ BPY_TRY(PyArg_ParseTuple(args, "")); \
+ prefix##_assignIpo(object, 0); \
+ Py_INCREF(Py_None); \
+ return Py_None; \
+}
+
+/** Macro used to define the MethodDef macro which is used again for defining
+ * module or object methods in the Method table, see e.g. BPY_scene.c
+ *
+ * Usage:
+
+ * _MethodDef(delete, Scene) expands to:
+ *
+ * {"delete", Scene_delete, METH_VARARGS, Scene_delete_doc}
+ */
+#define _MethodDef(func, prefix) \
+ {#func, prefix##_##func, METH_VARARGS, prefix##_##func##_doc}
+
+/** Mark the datablock wrapper as invalid. See BPY_text.c for details */
+#define MARK_INVALID(datablock) \
+ ((DataBlock *) datablock)->data = NULL
+
+/** Check whether datablock wrapper is valid */
+#define CHECK_VALIDDATA(x, msg) \
+ if (!x) { \
+ PyErr_SetString(PyExc_RuntimeError, msg); \
+ return 0; \
+ } \
+
+
+/* OBJECT ACCESS */
+
+/** retrieves name from BPYobject */
+#define getName(x) ((x)->id.name+2)
+#define getUsers(x) ((x)->id.us)
+#define getIDName(x) ((x)->name+2)
+#define getIDUsers(x) ((x)->us)
+
+#define object_getMaterials(object) (object)->mat
+
+/** rename object with name */
+
+/* ListBase of active object in scene */
+#define FirstBase (getGlobal()->scene->base.first)
+#define ActiveBase (getGlobal()->scene->basact)
+#define ObjectfromBase(base) (base->object)
+#define SelectedAndLayer(base) (((base)->flag & SELECT) && ((base)->lay & getGlobal()->vd->lay))
+/* Active object (bright pink) */
+
+#define ActiveObject (ActiveBase ? ObjectfromBase(ActiveBase) : NULL)
+
+/* returns 1 if textureface tf is selected/active, else 0 */
+#define isSelectedFace(tf) (((tf).flag & TF_SELECT) ? 1 : 0 )
+#define isActiveFace(tf) (((tf).flag & TF_ACTIVE) ? 1 : 0 )
+
+/* some conversion macros */
+
+#define PYBLOCK_AS(x, y) (x *) ((DataBlock *) y)->data
+#define PYBLOCK_AS_TEXT(x) PYBLOCK_AS(Text, x)
+#define PYBLOCK_AS_MATERIAL(x) PYBLOCK_AS(Material, x)
+#define PYBLOCK_AS_OBJECT(x) PYBLOCK_AS(Object, x)
+#define PYBLOCK_AS_MESH(x) PYBLOCK_AS(Mesh, x)
+#define PYBLOCK_AS_LAMP(x) PYBLOCK_AS(Lamp, x)
+#define PYBLOCK_AS_IPO(x) PYBLOCK_AS(Ipo, x)
+#define PYBLOCK_AS_DATA(x) PYBLOCK_AS(void, x)
diff --git a/source/blender/bpython/intern/BPY_main.c b/source/blender/bpython/intern/BPY_main.c
new file mode 100644
index 00000000000..17995476749
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_main.c
@@ -0,0 +1,672 @@
+/**
+ * blenkernel/py_main.c
+ * (cleaned up somewhat nzc apr-2001)
+
+ * $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 *****
+ *
+ */
+
+/* NOTE: all externally callable routines have the prefix BPY_
+ -- see also ../include/BPY_extern.h */
+
+#include "BPY_main.h"
+#include "BPY_modules.h"
+#include "BPY_macros.h"
+#include "DNA_space_types.h"
+
+#include "b_interface.h"
+#include "mydevice.h"
+#include "import.h"
+
+/* PROTOS */
+
+extern void init_frozenmodules(void); // frozen module library
+extern void initmxTextTools(void);
+extern void inittess(void); // tesselator module
+
+void init_ourImport(void);
+
+
+/* GLOBALS */
+
+PyObject* ErrorObject = NULL;
+PyObject* callback = NULL;
+PyObject* callbackArgs = NULL;
+PyObject* blenderprogname = NULL;
+ID* script_link_id = NULL;
+
+/*------------------------------------------------------------------------*/
+/* START PYTHON (from creator.c) */
+
+void INITMODULE(BLENDERMODULE)(void);
+
+struct _inittab blendermodules[] = {
+#ifndef SHAREDMODULE // Blender module can alternatively be compiled shared
+ #ifdef STATIC_TEXTTOOLS // see api.h
+ { "mxTextTools" , initmxTextTools },
+ #endif
+ { MODNAME(BLENDERMODULE) , INITMODULE(BLENDERMODULE) },
+#endif
+#ifdef NO_RELEASE
+ { "tess" , inittess }, // GLU tesselator wrapper module
+#endif
+ { 0, 0}
+};
+
+/* hack to make sure, inittab is extended only first time */
+
+static short g_is_extended = 0;
+
+/** (Re)initializes the Python Interpreter.
+ * This function should be only called if the Python interpreter
+ * was not yet initialized (check Py_IsInitialized() )
+ */
+
+static void initBPythonInterpreter(void)
+{
+ Py_Initialize();
+
+ init_ourImport(); /* our own import, later: security */
+ if (!BPY_CHECKFLAG(G_NOFROZEN)) {
+ init_frozenmodules(); /* initialize frozen modules unless disabled */
+ }
+ init_syspath();
+}
+
+/** This function initializes Blender Python. It should be called only
+ * once at start, which is currently not the case (GameEngine Python).
+ * Therefore, it contains some dirty workarounds. They will be thrown
+ * into the grachten once the different APIs are merged into something
+ * more consistent.
+ *
+ */
+
+void BPY_start_python(void)
+{
+ Py_SetProgramName("blender");
+ if (BPY_DEBUGFLAG) {
+
+ Py_VerboseFlag = 1;
+ Py_DebugFlag = 1;
+ } else {
+#ifndef EXPERIMENTAL
+ Py_FrozenFlag = 1; /* no warnings about non set PYTHONHOME */
+ Py_NoSiteFlag = 1; /* disable auto site module import */
+#endif
+ }
+
+ if (!g_is_extended) {
+ g_is_extended = 1;
+ PyImport_ExtendInittab(blendermodules); /* extend builtin module table */
+ }
+
+ initBPythonInterpreter();
+#ifdef NO_RELEASE
+ if (PyRun_SimpleString("import startup"))
+ {
+ BPY_warn(("init script not found, continuing anyway\n"));
+ PyErr_Clear();
+ return;
+ }
+#endif
+}
+
+/** Ends the Python interpreter. This cleans up all global variables
+ * Blender-Python descriptor objects will (MUST!) decref on their
+ * raw blender objects, so this function should be called more or less
+ * immediately before garbage collection actions.
+ */
+
+void BPY_end_python(void)
+{
+ Py_Finalize();
+}
+
+void BPY_free_compiled_text(Text* text)
+{
+ if (!text->compiled) return;
+ Py_DECREF((PyObject*) text->compiled);
+ text->compiled = NULL;
+}
+
+void syspath_append(PyObject *dir)
+{
+ PyObject *m, *d;
+ PyObject *o;
+
+ PyErr_Clear();
+ m = PyImport_ImportModule("sys");
+ d = PyModule_GetDict(m);
+ o = PyDict_GetItemString(d, "path");
+ if (!PyList_Check(o)) {
+ return;
+ }
+ PyList_Append(o, dir);
+ if (PyErr_Occurred()) {
+ Py_FatalError("could not build sys.path");
+ }
+ Py_DECREF(m);
+}
+
+/* build blender specific system path for external modules */
+
+void init_syspath(void)
+{
+ PyObject *path;
+ PyObject *m, *d;
+ PyObject *p;
+ char *c;
+
+
+ char execdir[PATH_MAXCHAR], *progname;
+
+ int n;
+
+ path = Py_BuildValue("s", bprogname);
+
+ m = PyImport_ImportModule(MODNAME(BLENDERMODULE) ".sys");
+ if (m) {
+ d = PyModule_GetDict(m);
+ PyDict_SetItemString(d, "progname", path);
+ Py_DECREF(m);
+ } else {
+ BPY_debug(("Warning: could not set Blender.sys.progname\n"));
+ }
+
+ progname = BLI_last_slash(bprogname); /* looks for the last dir separator */
+
+ c = Py_GetPath(); /* get python system path */
+ PySys_SetPath(c); /* initialize */
+
+ n = progname - bprogname;
+ if (n > 0) {
+ strncpy(execdir, bprogname, n);
+ execdir[n] = '\0';
+
+ p = Py_BuildValue("s", execdir);
+ syspath_append(p); /* append to module search path */
+
+ /* set Blender.sys.progname */
+ } else {
+ BPY_debug(("Warning: could not determine argv[0] path\n"));
+ }
+ /* TODO look for the blender executable in the search path */
+ BPY_debug(("append to syspath: %s\n", U.pythondir));
+ if (U.pythondir) {
+ p = Py_BuildValue("s", U.pythondir);
+ syspath_append(p); /* append to module search path */
+ }
+ BPY_debug(("append done\n"));
+}
+
+
+#define FILENAME_LENGTH 24
+typedef struct _ScriptError {
+ char filename[FILENAME_LENGTH];
+ int lineno;
+} ScriptError;
+
+ScriptError g_script_error;
+
+int BPY_Err_getLinenumber()
+{
+ return g_script_error.lineno;
+}
+
+const char *BPY_Err_getFilename()
+{
+ return g_script_error.filename;
+}
+
+/** Returns (PyString) filename from a traceback object */
+
+PyObject *traceback_getFilename(PyObject *tb)
+{
+ PyObject *v;
+
+ v = PyObject_GetAttrString(tb, "tb_frame"); Py_DECREF(v);
+ v = PyObject_GetAttrString(v, "f_code"); Py_DECREF(v);
+ v = PyObject_GetAttrString(v, "co_filename");
+ return v;
+}
+
+/** Blender Python error handler. This catches the error and stores
+ * filename and line number in a global
+ */
+
+void BPY_Err_Handle(Text *text)
+{
+ PyObject *exception, *err, *tb, *v;
+
+ PyErr_Fetch(&exception, &err, &tb);
+
+ if (!exception && !tb) {
+ printf("FATAL: spurious exception\n");
+ return;
+ }
+
+ strcpy(g_script_error.filename, getName(text));
+
+ if (exception && PyErr_GivenExceptionMatches(exception, PyExc_SyntaxError)) {
+ // no traceback available when SyntaxError
+ PyErr_Restore(exception, err, tb); // takes away reference!
+ PyErr_Print();
+ v = PyObject_GetAttrString(err, "lineno");
+ g_script_error.lineno = PyInt_AsLong(v);
+ Py_XDECREF(v);
+ return;
+ } else {
+ PyErr_NormalizeException(&exception, &err, &tb);
+ PyErr_Restore(exception, err, tb); // takes away reference!
+ PyErr_Print();
+ tb = PySys_GetObject("last_traceback");
+ Py_INCREF(tb);
+
+// check traceback objects and look for last traceback in the
+// same text file. This is used to jump to the line of where the
+// error occured. If the error occured in another text file or module,
+// the last frame in the current file is adressed
+
+ while (1) {
+ v = PyObject_GetAttrString(tb, "tb_next");
+ if (v == Py_None ||
+ strcmp(PyString_AsString(traceback_getFilename(v)), getName(text)))
+ break;
+ Py_DECREF(tb);
+ tb = v;
+ }
+
+ v = PyObject_GetAttrString(tb, "tb_lineno");
+ g_script_error.lineno = PyInt_AsLong(v);
+ Py_XDECREF(v);
+ v = traceback_getFilename(tb);
+ strncpy(g_script_error.filename, PyString_AsString(v), FILENAME_LENGTH);
+ Py_XDECREF(v);
+ Py_DECREF(tb);
+ }
+}
+
+/** Runs a Python string in the global name space of the given dictionary
+ 'globaldict' */
+
+static PyObject *newGlobalDictionary(void)
+{
+ PyObject *d = PyDict_New();
+ PyDict_SetItemString(d, "__builtins__", PyEval_GetBuiltins());
+ PyDict_SetItemString(d, "__name__", PyString_FromString("__main__"));
+ return d;
+}
+
+static void releaseGlobalDictionary(PyObject *d)
+{
+ BPY_debug(("--- CLEAR namespace\n"));
+ PyDict_Clear(d);
+ Py_DECREF(d); // release dictionary
+}
+
+PyObject *BPY_runPython(Text *text, PyObject *globaldict)
+{
+ PyObject *ret;
+ char* buf = NULL;
+
+ if (!text->compiled)
+ {
+ buf = txt_to_buf(text);
+ /* bah, what a filthy hack -- removed */
+ /* strcat(buf, "\n"); */
+ text->compiled = Py_CompileString(buf, getName(text), Py_file_input);
+ MEM_freeN(buf);
+ if (PyErr_Occurred())
+ {
+ BPY_free_compiled_text(text);
+ return 0;
+ }
+ }
+ BPY_debug(("Run Python script \"%s\" ...\n", getName(text)));
+ ret = PyEval_EvalCode(text->compiled, globaldict, globaldict);
+ return ret;
+}
+
+/** This function is executed whenever ALT+PKEY is pressed -> drawtext.c
+ It returns the global namespace dictionary of the script context
+ (which is created newly when CLEAR_NAMESPACE is defined).
+ This may be stored in the SpaceText instance to give control over
+ namespace persistence. Remember that the same script may be executed
+ in several windows..
+ Namespace persistence is desired for scripts that use the GUI and
+ store callbacks to the current script.
+*/
+
+PyObject *BPY_txt_do_python(SpaceText *st)
+{
+ PyObject* d = NULL;
+ PyObject *ret;
+ Text *text = st->text;
+
+ if (!text)
+ {
+ return NULL;
+ }
+
+ /* TODO: make this an option: */
+#ifdef CLEAR_NAMESPACE
+ BPY_debug(("--- enable clear namespace\n"));
+ st->flags |= ST_CLEAR_NAMESPACE;
+#endif
+
+#ifdef CLEAR_NAMESPACE
+ d = newGlobalDictionary();
+#else
+ d = PyModule_GetDict(PyImport_AddModule("__main__"));
+#endif
+
+ ret = BPY_runPython(text, d);
+
+ if (!ret) {
+#ifdef CLEAR_NAMESPACE
+ releaseGlobalDictionary(d);
+#endif
+ BPY_Err_Handle(text);
+ Py_Finalize();
+ initBPythonInterpreter();
+ return NULL;
+ }
+ else
+ Py_DECREF(ret);
+
+
+ /* The following lines clear the global name space of the python
+ * interpreter. This is desired to release objects after execution
+ * of a script (remember that each wrapper object increments the refcount
+ * of the Blender Object.
+
+ * Exception: scripts that use the GUI rely on the
+ * persistent global namespace, so they need a workaround: The namespace
+ * is released when the GUI is exit.
+ * See opy_draw.c:Method_Register()
+ *
+ */
+
+#ifdef CLEAR_NAMESPACE
+ if (st->flags & ST_CLEAR_NAMESPACE) {
+ releaseGlobalDictionary(d);
+ garbage_collect(getGlobal()->main);
+ }
+#endif
+
+ return d;
+}
+
+/****************************************/
+/* SCRIPTLINKS */
+
+static void do_all_scriptlist(ListBase* list, short event)
+{
+ ID *id;
+
+ id = list->first;
+ while (id)
+ {
+ BPY_do_pyscript (id, event);
+ id = id->next;
+ }
+}
+
+void BPY_do_all_scripts(short event)
+{
+ do_all_scriptlist(getObjectList(), event);
+ do_all_scriptlist(getLampList(), event);
+ do_all_scriptlist(getCameraList(), event);
+ do_all_scriptlist(getMaterialList(), event);
+ do_all_scriptlist(getWorldList(), event);
+
+ BPY_do_pyscript(&scene_getCurrent()->id, event);
+}
+
+
+char *event_to_name(short event)
+{
+ switch (event) {
+ case SCRIPT_FRAMECHANGED:
+ return "FrameChanged";
+ case SCRIPT_ONLOAD:
+ return "OnLoad";
+ case SCRIPT_REDRAW:
+ return "Redraw";
+ default:
+ return "Unknown";
+ }
+}
+
+
+void BPY_do_pyscript(ID *id, short event)
+{
+ int i, offset;
+ char evName[24] = "";
+ char* structname = NULL;
+ ScriptLink* scriptlink;
+ PyObject *globaldict;
+
+ switch(GET_ID_TYPE(id)) {
+ case ID_OB: structname= "Object"; break;
+ case ID_LA: structname= "Lamp"; break;
+ case ID_CA: structname= "Camera"; break;
+ case ID_MA: structname= "Material"; break;
+ case ID_WO: structname= "World"; break;
+ case ID_SCE: structname= "Scene"; break;
+ default: return;
+ }
+
+ offset = BLO_findstruct_offset(structname, "scriptlink");
+ if (offset < 0)
+ {
+ BPY_warn(("Internal error, unable to find script link\n"));
+ return;
+ }
+ scriptlink = (ScriptLink*) (((char*)id) + offset);
+
+ /* no script provided */
+ if (!scriptlink->totscript) return;
+
+/* Debugging output */
+ switch (event)
+ {
+ case SCRIPT_FRAMECHANGED:
+ strcpy(evName, "SCRIPT_FRAMECHANGED");
+ BPY_debug(("do_pyscript(%s, %s)\n", getIDName(id), evName));
+ break;
+ case SCRIPT_ONLOAD:
+ strcpy(evName, "SCRIPT_ONLOAD");
+ BPY_debug(("do_pyscript(%s, %s)\n", getIDName(id), evName));
+ break;
+ case SCRIPT_REDRAW:
+ strcpy(evName, "SCRIPT_REDRAW");
+ BPY_debug(("do_pyscript(%s, %s)\n", getIDName(id), evName));
+ break;
+ default:
+ BPY_debug(("do_pyscript(): This should not happen !!!"));
+ break;
+ }
+
+/* END DEBUGGING */
+#ifndef SHAREDMODULE
+ set_scriptlinks(id, event);
+#endif
+ disable_where_script(1);
+ for (i = 0; i < scriptlink->totscript; i++)
+ {
+ if (scriptlink->flag[i] == event && scriptlink->scripts[i])
+ {
+ BPY_debug(("Evaluate script \"%s\" ...\n",
+ getIDName(scriptlink->scripts[i])));
+ script_link_id = id;
+#ifdef CLEAR_NAMESPACE
+ globaldict = newGlobalDictionary();
+#else
+ globaldict = PyModule_GetDict(PyImport_AddModule("__main__"));
+#endif
+ BPY_runPython((Text*) scriptlink->scripts[i], globaldict);
+#ifdef CLEAR_NAMESPACE
+ releaseGlobalDictionary(globaldict);
+#endif
+
+ script_link_id = NULL;
+ BPY_debug(("... done\n"));
+ }
+ }
+#ifndef SHAREDMODULE
+ release_scriptlinks(id);
+#endif
+ disable_where_script(0);
+}
+
+void BPY_clear_bad_scriptlink(ID *id, Text *byebye)
+{
+ ScriptLink* scriptlink;
+ int offset = -1;
+ char* structname = NULL;
+ int i;
+
+ switch (GET_ID_TYPE(id)) {
+ case ID_OB: structname = "Object"; break;
+ case ID_LA: structname = "Lamp"; break;
+ case ID_CA: structname = "Camera"; break;
+ case ID_MA: structname = "Material"; break;
+ case ID_WO: structname = "World"; break;
+ case ID_SCE: structname = "Scene"; break;
+ }
+
+ if (!structname) return;
+
+ offset= BLO_findstruct_offset(structname, "scriptlink");
+
+ if (offset<0) return;
+
+ scriptlink= (ScriptLink *) (((char *)id) + offset);
+
+ for(i=0; i<scriptlink->totscript; i++)
+ if ((Text*)scriptlink->scripts[i] == byebye)
+ scriptlink->scripts[i] = NULL;
+}
+
+void BPY_clear_bad_scriptlist(ListBase *list, Text *byebye)
+{
+ ID *id;
+
+ id= list->first;
+ while (id)
+ {
+ BPY_clear_bad_scriptlink(id, byebye);
+ id= id->next;
+ }
+}
+
+void BPY_clear_bad_scriptlinks(Text *byebye)
+{
+ BPY_clear_bad_scriptlist(getObjectList(), byebye);
+ BPY_clear_bad_scriptlist(getLampList(), byebye);
+ BPY_clear_bad_scriptlist(getCameraList(), byebye);
+ BPY_clear_bad_scriptlist(getMaterialList(), byebye);
+ BPY_clear_bad_scriptlist(getWorldList(), byebye);
+ BPY_clear_bad_scriptlink(&scene_getCurrent()->id, byebye);
+ allqueue(REDRAWBUTSSCRIPT, 0);
+}
+
+void BPY_free_scriptlink(ScriptLink *slink)
+{
+ if (slink->totscript)
+ {
+ if(slink->flag) MEM_freeN(slink->flag);
+ if(slink->scripts) MEM_freeN(slink->scripts);
+ }
+}
+
+void BPY_copy_scriptlink(ScriptLink *scriptlink)
+{
+ void *tmp;
+
+ if (scriptlink->totscript)
+ {
+ tmp = scriptlink->scripts;
+ scriptlink->scripts = MEM_mallocN(sizeof(ID*)*scriptlink->totscript, "scriptlistL");
+ memcpy(scriptlink->scripts, tmp, sizeof(ID*)*scriptlink->totscript);
+
+ tmp = scriptlink->flag;
+ scriptlink->flag = MEM_mallocN(sizeof(short)*scriptlink->totscript, "scriptlistF");
+ memcpy(scriptlink->flag, tmp, sizeof(short)*scriptlink->totscript);
+ }
+}
+
+/*
+ * Python alien graphics format conversion framework
+ *
+ * $Id$
+ *
+ *
+ *
+ */
+
+/* import importloader module with registered importers */
+#include "BPY_extern.h"
+#include "Python.h"
+
+
+int BPY_call_importloader(char *name)
+{
+ PyObject *mod, *tmp, *meth, *args;
+ int i, success = 0;
+
+ init_syspath();
+ mod = PyImport_ImportModule("Converter.importloader");
+ if (mod) {
+ meth = PyObject_GetAttrString(mod, "process"); // new ref
+ args = Py_BuildValue("(s)", name);
+ tmp = PyEval_CallObject(meth, args);
+ Py_DECREF(meth);
+ if (PyErr_Occurred()) {
+ PyErr_Print();
+ }
+
+ if (tmp) {
+ i = PyInt_AsLong(tmp);
+ if (i)
+ success = 1;
+ Py_DECREF(tmp);
+ }
+ Py_DECREF(mod);
+ } else {
+ PyErr_Print();
+ BPY_warn(("couldn't import 'importloader' \n"));
+ }
+ return success;
+}
+
+// more to come...
diff --git a/source/blender/bpython/intern/BPY_main.h b/source/blender/bpython/intern/BPY_main.h
new file mode 100644
index 00000000000..526aa21df8f
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_main.h
@@ -0,0 +1,86 @@
+/* BlenderPython Main routine header *
+ $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 *****
+ */
+// Note: Functions prefixed with BPY_ are called from blenkernel routines */
+
+
+#include "Python.h" /* The python includes themselves. */
+#include "compile.h" /* to give us PyCodeObject */
+#include "eval.h" /* for PyEval_EvalCode.h */
+
+/* blender stuff */
+#include "MEM_guardedalloc.h"
+#include "BLI_blenlib.h"
+#include "BLI_editVert.h"
+#include "BLI_fileops.h" /* string handling of filenames */
+
+#include "BKE_bad_level_calls.h"
+// #include "BKE_editmesh.h"
+
+#include "BKE_global.h"
+#include "BKE_main.h"
+
+#include "BLO_genfile.h" // for BLO_findstruct_offset only
+#include "BKE_text.h"
+#include "BKE_displist.h"
+#include "BKE_mesh.h"
+#include "BKE_material.h"
+#include "BKE_object.h"
+#include "BKE_screen.h"
+#include "BKE_scene.h"
+#include "BKE_library.h"
+#include "BKE_text.h"
+
+#include "b_interface.h"
+
+/* prototypes of externally used functions are HERE */
+#include "BPY_extern.h"
+
+ /* I just chucked some prototypes
+ * here... not sure where they should
+ * really be. -zr
+ */
+extern struct ID * script_link_id;
+
+extern PyObject *g_blenderdict;
+extern int g_window_redrawn;
+extern int disable_force_draw;
+
+void window_update_curCamera(Object *);
+PyObject *ConstObject_New(void);
+void insertConst(PyObject *dict, char *name, PyObject *item);
+PyObject *Windowmodule_Redraw(PyObject *self, PyObject *args);
+
+char *event_to_name(short event);
+void syspath_append(PyObject *dir);
+void init_syspath(void);
+void set_scriptlinks(ID *id, short event);
+void release_scriptlinks(ID *id);
diff --git a/source/blender/bpython/intern/BPY_modules.h b/source/blender/bpython/intern/BPY_modules.h
new file mode 100644
index 00000000000..98f9170fe9b
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_modules.h
@@ -0,0 +1,47 @@
+/* Prototypes for all fixed module init routines
+ * $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 *****
+ * these prototypes and init functions should be homogenized
+ */
+
+extern PyObject *init_blender(void);
+extern PyObject *init_py_nmesh(void);
+extern PyObject *init_py_draw(void);
+extern PyObject *init_py_bgl(void);
+extern PyObject *initWindow(void);
+extern PyObject *initImage(void);
+extern PyObject *init_types(PyObject *dict);
+void init_py_vector(void);
+void init_py_matrix(void);
+void init_Datablockmodules(PyObject *dict);
+void initGUI(void);
+
+
+
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;
+}
+
diff --git a/source/blender/bpython/intern/BPY_scene.c b/source/blender/bpython/intern/BPY_scene.c
new file mode 100644
index 00000000000..19e992e6bb1
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_scene.c
@@ -0,0 +1,506 @@
+/** Scene module; access to Scene objects in Blender
+ *
+ * Scene objects are no longer DataBlock objects, but referred
+ * by name. This makes it a little slower, but safer - Scene properties
+ * can no longer be accessed after a Scene was deleted.
+ *
+ * $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 "BKE_scene.h"
+#include "BIF_drawscene.h"
+
+#include "BSE_headerbuttons.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_scene_types.h"
+#include "opy_datablock.h"
+#include "b_interface.h"
+
+#include "BPY_macros.h"
+#include "BPY_window.h"
+
+/* DEFINES */
+
+#define CHECK_VALIDSCENE(x) CHECK_VALIDDATA(x, \
+ "Scene was deleted!")
+
+#define PyScene_AsScene(x) \
+ getSceneByName(((PyScene *) x)->name)
+
+/* PROTOS */
+
+PyObject *PyScene_FromScene(Scene *scene);
+
+/************************/
+/* Helper routines */
+
+/* returns a python list of the objects of the Base 'base' */
+
+static PyObject *objectlist_from_base(Base *base)
+{
+ PyObject *pylist= PyList_New(0);
+ PyObject *b;
+
+ while (base) {
+ b = (PyObject *) DataBlock_fromData(base->object);
+ PyList_Append(pylist, b);
+ Py_XDECREF(b); // because PyList_Append increfs!
+ base = base->next;
+ }
+ return pylist;
+}
+
+/* Scene object */
+
+typedef struct {
+ PyObject_VAR_HEAD
+ char name[32];
+} PyScene;
+
+static PyObject *newPyScene(char *name);
+
+/** Returns scene by name. Can be NULL if not found */
+Scene *getSceneByName(char *name)
+{
+ return (Scene *) getFromList(getSceneList(), name);
+}
+
+/************************/
+/* Scene object methods */
+
+static char Scene_getChildren_doc[] =
+"() - returns list of scene children objects";
+
+static PyObject *Scene_getChildren(PyObject *self, PyObject *args)
+{
+ Scene *scene = PyScene_AsScene(self);
+
+ CHECK_VALIDSCENE(scene)
+
+ BPY_TRY(PyArg_ParseTuple(args, ""));
+ return objectlist_from_base(scene->base.first);
+}
+
+static char Scene_getCurrentCamera_doc[] =
+"() - returns current active camera";
+
+static PyObject *Scene_getCurrentCamera(PyObject *self, PyObject *args)
+{
+ Scene *scene = PyScene_AsScene(self);
+ Object *object;
+
+ CHECK_VALIDSCENE(scene)
+
+ object = scene->camera;
+ if (!object) {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+ return DataBlock_fromData(object);
+}
+
+static char Scene_setCurrentCamera_doc[] =
+"(camera) - sets current active camera. 'camera' must be a valid camera\n\
+Object";
+
+static PyObject *Scene_setCurrentCamera(PyObject *self, PyObject *args)
+{
+ Scene *scene = PyScene_AsScene(self);
+ Object *object;
+ DataBlock *block;
+
+ CHECK_VALIDSCENE(scene)
+
+ BPY_TRY(PyArg_ParseTuple(args, "O!", &DataBlock_Type, &block));
+ if (!DataBlock_isType(block, ID_OB)) {
+ PyErr_SetString(PyExc_TypeError, "Object type expected!");
+ return NULL;
+ }
+
+ object = PYBLOCK_AS_OBJECT(block);
+
+ scene->camera = object;
+ if (scene_getCurrent() == scene) // update current scene display
+ window_update_curCamera(object);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+#define SCENE_GETDIR(name, elem) \
+static PyObject *Scene_get##name(PyObject *self, PyObject *args) \
+{ \
+ Scene *scene = PyScene_AsScene(self); \
+ CHECK_VALIDSCENE(scene) \
+ return PyString_FromString(scene->elem); \
+} \
+
+static char Scene_getRenderdir_doc[] =
+"() - returns directory where rendered images are saved to";
+
+SCENE_GETDIR(Renderdir, r.pic)
+
+static char Scene_getBackbufdir_doc[] =
+"() - returns the Backbuffer images location";
+
+SCENE_GETDIR(Backbufdir, r.backbuf)
+
+#define INVALID_FRAME -99999
+
+static char Scene_frameSettings_doc[] =
+"(start, end, current) - sets the scene's frame settings:\n\
+ start : start frame\n\
+ end : end frame\n\
+ current: current frame\n\
+If a frame value is negative, it is not set.\n\
+\n\
+Return value: the current frame settings (start, end, current)";
+
+static PyObject *Scene_frameSettings(PyObject *self, PyObject *args)
+{
+ RenderData *rd = 0;
+ int current = INVALID_FRAME;
+ int start = INVALID_FRAME;
+ int end = INVALID_FRAME;
+ Scene *scene = PyScene_AsScene(self);
+
+ CHECK_VALIDSCENE(scene)
+
+ rd = &scene->r;
+
+ BPY_TRY(PyArg_ParseTuple(args, "|iii", &start, &end, &current));
+ if (start > 0) {
+ rd->sfra = start;
+ }
+ if (end > 0) {
+ rd->efra = end;
+ }
+ if (current > 0) {
+ rd->cfra = current;
+ }
+ return Py_BuildValue("(iii)", rd->sfra, rd->efra, rd->cfra);
+}
+
+
+static char Scene_makeCurrent_doc[] =
+"() - makes Scene the current Scene";
+
+static PyObject *Scene_makeCurrent(PyObject *self, PyObject *args)
+{
+ Scene *scene = PyScene_AsScene(self);
+
+ CHECK_VALIDSCENE(scene)
+
+ set_scene(scene);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static char Scene_copy_doc[] =
+"(duplicate_objects = 1) - make a copy of a scene\n\
+'The optional argument defines, how the scene's children objects are\n\
+duplicated:\n\
+\n\
+0: Link Objects\n\
+1: Link Object data\n\
+2: Full Copy";
+
+static PyObject *Scene_copy(PyObject *self, PyObject *args)
+{
+ Scene *scene = PyScene_AsScene(self);
+
+ int dup_objects = 0;
+
+ CHECK_VALIDSCENE(scene)
+
+ BPY_TRY(PyArg_ParseTuple(args, "|i", &dup_objects));
+
+ return PyScene_FromScene(copy_scene(scene, dup_objects));
+}
+
+static char Scene_update_doc[]= "() - Update scene\n\
+This function explicitely resorts the base list of a newly created object\n\
+hierarchy.";
+
+static PyObject *Scene_update(PyObject *self, PyObject *args)
+{
+ Scene *scene = PyScene_AsScene(self);
+
+ CHECK_VALIDSCENE(scene)
+
+ BPY_TRY(PyArg_ParseTuple(args, ""));
+ sort_baselist(scene);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static char Scene_link_doc[]= "(object) - Links object to scene";
+
+/** Links an object with a scene */
+static PyObject *Scene_link(PyObject *self, PyObject *args)
+{
+ DataBlock *block;
+ Object *object;
+ Scene *scene = PyScene_AsScene(self);
+ CHECK_VALIDSCENE(scene)
+
+ BPY_TRY(PyArg_ParseTuple(args, "O!", &DataBlock_Type, &block));
+ if (DataBlock_type(block) != ID_OB) {
+ PyErr_SetString(PyExc_TypeError, "link: invalid Object type");
+ return NULL;
+ }
+ object = PYBLOCK_AS_OBJECT(block);
+ if (!scene_linkObject(scene, object))
+ {
+ PyErr_SetString(PyExc_RuntimeError, "Object already in scene!");
+ return NULL;
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+/** unlinks (removes) an object from a scene */
+
+static char Scene_unlink_doc[]= "(object) - Unlinks object from scene";
+
+static PyObject *Scene_unlink(PyObject *self, PyObject *args)
+{
+ PyObject *retval;
+ DataBlock *block;
+ Object *object;
+ Scene *scene = PyScene_AsScene(self);
+ CHECK_VALIDSCENE(scene)
+
+ BPY_TRY(PyArg_ParseTuple(args, "O!", &DataBlock_Type, &block));
+ if (DataBlock_type(block) != ID_OB) {
+ PyErr_SetString(PyExc_TypeError, "unlink: invalid Object type");
+ return NULL;
+ }
+ object = PYBLOCK_AS_OBJECT(block);
+
+ if (!scene_unlinkObject(scene, object))
+ retval = Py_BuildValue("i", 0);
+ else
+ retval = Py_BuildValue("i", 1);
+ Py_INCREF(retval);
+ return retval;
+}
+
+#undef MethodDef
+#define MethodDef(func) _MethodDef(func, Scene)
+
+/* these are the scene object methods */
+static struct PyMethodDef Scene_methods[] = {
+ MethodDef(copy),
+ MethodDef(link),
+ MethodDef(unlink),
+ MethodDef(getChildren),
+ MethodDef(getCurrentCamera),
+ MethodDef(setCurrentCamera),
+ MethodDef(getRenderdir),
+ MethodDef(getBackbufdir),
+ MethodDef(frameSettings),
+ MethodDef(makeCurrent),
+ MethodDef(update),
+ {NULL, NULL}
+};
+
+static void PyScene_dealloc(PyObject *self)
+{
+ PyMem_DEL(self);
+}
+
+static PyObject *PyScene_getattr(PyObject *self, char *attr)
+{
+ Scene *scene;
+ if (!strcmp(attr, "name")) {
+ return PyString_FromString(((PyScene *) self)->name);
+ } else if (!strcmp(attr, "users")) {
+ scene = PyScene_AsScene(self);
+ return PyInt_FromLong(getUsers(scene));
+ } else if (!strcmp(attr, "block_type")) {
+ return Py_BuildValue("s", "Scene");
+ }
+ return Py_FindMethod(Scene_methods, (PyObject *) self, attr);
+}
+
+PyObject *PyScene_repr(PyScene *self)
+{
+ char s[256];
+ Scene *scene = PyScene_AsScene(self);
+ if (scene)
+ sprintf (s, "[Scene %.32s]", getName(scene));
+ else
+ sprintf (s, "[deleted Scene]");
+ return Py_BuildValue("s", s);
+}
+
+static PyTypeObject PyScene_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "Scene", /*tp_name*/
+ sizeof(PyScene), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor) PyScene_dealloc, /*tp_dealloc*/
+ (printfunc)0, /*tp_print*/
+ (getattrfunc)PyScene_getattr, /*tp_getattr*/
+ (setattrfunc)0, /*tp_setattr*/
+ (cmpfunc)0, /*tp_compare*/
+ (reprfunc)PyScene_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ (hashfunc)0, /*tp_hash*/
+ (ternaryfunc)0, /*tp_call*/
+ (reprfunc)0, /*tp_str*/
+
+ /* Space for future expansion */
+ 0L,0L,0L,0L,
+ 0 /* Documentation string */
+};
+
+static PyObject *newPyScene(char *name)
+{
+ PyScene *scene = PyObject_NEW(PyScene, &PyScene_Type);
+ strncpy(scene->name, name, 31);
+ return (PyObject *) scene;
+}
+
+PyObject *PyScene_FromScene(Scene *scene)
+{
+ if (scene)
+ return newPyScene(getName(scene));
+ else {
+ Py_INCREF(Py_None);
+ return Py_None;
+ }
+}
+
+PyObject *PyScene_FromVoid(void *scene)
+{
+ return PyScene_FromScene((Scene *) scene);
+}
+
+
+/************************/
+/* Scene module methods */
+
+static char Scenemodule_get_doc[] =
+"(name = None) - get Scene 'name' from Blender, if 'name' specified.\n\
+Otherwise, a list of all Scenes is returned";
+
+static PyObject *Scenemodule_get(PyObject *self, PyObject *args)
+{
+ char *name= NULL;
+ BPY_TRY(PyArg_ParseTuple(args, "|s", &name));
+
+ if (name) {
+ return PyScene_FromScene(getSceneByName(name));
+ } else {
+ return BPY_PyList_FromIDList(getSceneList(), PyScene_FromVoid);
+ }
+}
+
+static char Scenemodule_New_doc[] =
+"(name = None) - Create new scene with (optionally given)\n\
+name.";
+
+static PyObject *Scenemodule_New(PyObject *self, PyObject *args)
+{
+ Scene *scene;
+ char *name = "Scene";
+
+ BPY_TRY(PyArg_ParseTuple(args, "|s", &name));
+ scene = add_scene(name);
+ return newPyScene(name);
+}
+
+static char Scenemodule_getCurrent_doc[] =
+"() - returns currently active Scene";
+
+static PyObject *Scenemodule_getCurrent(PyObject *self, PyObject *args)
+{
+ return newPyScene(getName(scene_getCurrent()));
+}
+
+static char Scenemodule_unlink_doc[] =
+"(scene) - deletes the Scene 'scene' from Blender\n\
+The Scene must be empty before removing it";
+
+static PyObject *Scenemodule_unlink(PyObject *self, PyObject *args)
+{
+ PyObject *sceneobj;
+ Scene *scene;
+
+ if(!PyArg_ParseTuple(args, "O!", &PyScene_Type, &sceneobj)) {
+ PyErr_SetString(PyExc_TypeError, "Scene object expected!");
+ return NULL;
+ }
+
+ scene = PyScene_AsScene(sceneobj);
+ free_libblock(getSceneList(), scene);
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/*****************/
+/* METHOD TABLES */
+
+/* these are the module methods */
+
+#undef MethodDef
+#define MethodDef(func) _MethodDef(func, Scenemodule)
+
+struct PyMethodDef Scenemodule_methods[] = {
+ MethodDef(get),
+ MethodDef(getCurrent),
+ MethodDef(New),
+ MethodDef(unlink),
+ {NULL, NULL}
+};
+
+PyObject *initScene()
+{
+ PyObject *mod;
+ PyScene_Type.ob_type = &PyType_Type;
+ mod= Py_InitModule(MODNAME(BLENDERMODULE) ".Scene",
+ Scenemodule_methods);
+ return mod;
+}
+
+
diff --git a/source/blender/bpython/intern/BPY_text.c b/source/blender/bpython/intern/BPY_text.c
new file mode 100644
index 00000000000..855e12a6b9f
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_text.c
@@ -0,0 +1,295 @@
+/** Text buffer module; access to Text buffers in Blender
+ *
+ * ***** 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 *****
+ *
+ * The ownership relations of a Text buffer are in Blender pretty clear:
+ * The Text editor is ALWAYS the container for all text objects.
+ * Currently, the Text object is implemented as a free object though, as
+ * the ownership of a Text might change in future. The reference counting of
+ * a Text object IN BLENDER is not really maintained though (for the above ownership
+ * reason).
+ * This introduces a problem if a Text object is accessed after it was actually
+ * deleted. Currently, a 'guard' is implemented for access after deletion INSIDE
+ * A SCRIPT. The Blender GUI is not aware of the wrapper though, so if a Text buffer
+ * is cleared while the script is accessing the wrapper, bad results are expected.
+ * BUT: This currently can not happen, unless a Python script is running in the
+ * background as a separate thread...
+ *
+ * TODO:
+ *
+ * either a):
+ * figure out ownership and implement each access to the text buffer by
+ * name and not by reference (pointer). This will require quite some additions
+ * in the generic DataBlock access (opy_datablock.c)
+ *
+ * or b):
+ * implement reference counting for text buffers properly, so that a deletion
+ * of a text buffer by the GUI does not result in a release of the actual
+ * Text object, but by a DECREF. The garbage collector (or wrapper deletion method)
+ * will then free the Text object.
+ *
+ * To be discussed and evaluated.
+ *
+ * $Id$
+ *
+ */
+
+
+#include "Python.h"
+#include "stringobject.h"
+
+#include "BPY_macros.h"
+#include "BKE_text.h"
+#include "BIF_drawtext.h"
+#include "DNA_text_types.h"
+#include "BPY_extern.h"
+#include "BKE_sca.h"
+
+#include "b_interface.h"
+#include "opy_datablock.h"
+
+DATABLOCK_GET(Textmodule, text object, getTextList())
+
+#define CHECK_VALIDTEXT(x) CHECK_VALIDDATA(x, \
+ "Text was deleted; illegal access!")
+
+#define OFF 1
+
+static char Textmodule_New_doc[] =
+"(name = None, follow = 0) - Create new text buffer with (optionally given)\n\
+name.\n\
+If 'follow' == 1, the text display always follows the cursor";
+
+static PyObject *Textmodule_New(PyObject *self, PyObject *args)
+{
+ Text *text;
+ PyObject *textobj;
+ PyObject *name = NULL;
+ int follow = 0;
+
+ text = add_empty_text();
+ BPY_TRY(PyArg_ParseTuple(args, "|O!i", &PyString_Type, &name, &follow));
+ textobj = DataBlock_fromData(text);
+ if (follow) {
+ text->flags |= TXT_FOLLOW;
+ }
+ if (name) {
+ DataBlock_setattr(textobj, "name", name);
+ }
+ return textobj;
+}
+
+static char Textmodule_unlink_doc[] =
+"(text) - remove text object 'text' from the text window";
+
+/** This function removes the text entry from the text editor.
+ * The text is not freed here, but inside the garbage collector
+ */
+
+static PyObject *Textmodule_unlink(PyObject *self, PyObject *args)
+{
+ PyObject *textobj;
+ Text *text;
+
+ BPY_TRY(PyArg_ParseTuple(args, "O!", &DataBlock_Type, &textobj));
+ if (!DataBlock_isType((DataBlock *) textobj, ID_TXT)) {
+ PyErr_SetString(PyExc_TypeError, "Text object expected!");
+ return NULL;
+ }
+
+ text = PYBLOCK_AS_TEXT(textobj);
+ BPY_clear_bad_scriptlinks(text);
+ free_text_controllers(text);
+ unlink_text(text);
+ /* We actually should not free the text object here, but let the
+ * __del__ method of the wrapper do the job. This would require some
+ * changes in the GUI code though..
+ * So we mark the wrapper as invalid by setting wrapper->data = 0 */
+ free_libblock(getTextList(), text);
+ MARK_INVALID(textobj);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+
+/* these are the module methods */
+struct PyMethodDef Textmodule_methods[] = {
+ {"get", Textmodule_get, METH_VARARGS, Textmodule_get_doc},
+ {"New", Textmodule_New, METH_VARARGS, Textmodule_New_doc},
+ {"unlink", Textmodule_unlink, METH_VARARGS, Textmodule_unlink_doc},
+ {NULL, NULL}
+};
+
+// Text object properties
+
+DataBlockProperty Text_Properties[]= {
+ {NULL}
+};
+
+/* This is uncommented only for an example on how (probably) not to
+ * do it :-)
+ * It's a bad idea in this case to have a wrapper object destroy its wrapped object
+ * because checks have to be done whether the wrapper is still accessed after
+ * the wrapped objects deletion.
+ * Better: unlink the object from it's owner: Blender.Text.unlink(text)
+ * That way the object is not yet freed, but its refcount set to 0.
+ * The garbage collector takes care of the rest..
+ * But it has to be made sure that the wrapper object is no longer kept around
+ * after the script ends.
+ *
+
+static char Text_delete_doc[] =
+"() - delete text from Text window";
+
+static PyObject *Text_delete(PyObject *self, PyObject *args)
+{
+ Text *text = PYBLOCK_AS_TEXT(self);
+ // we have to check for validity, as the Text object is only a
+ // descriptor...
+ CHECK_VALIDTEXT(text)
+ BPY_TRY(PyArg_ParseTuple(args, ""));
+ BPY_clear_bad_scriptlinks(text);
+ free_text_controllers(text);
+ unlink_text(text);
+ free_libblock(&getGlobal()->main->text, text);
+ ((DataBlock *) self)->data = NULL;
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+*/
+
+/** This method gets called on the wrapper objects deletion.
+ * Here we release the Text object if its refcount is == 0
+
+ -- CURRENTLY UNCOMMENTED -- needs change in Blender kernel..
+
+static PyObject *Text_del(PyObject *self, PyObject *args)
+{
+ Text *text = PYBLOCK_AS_TEXT(self);
+ if (BOB_REFCNT((ID *) text) == 0) {
+ free_libblock(&getGlobal()->main->text, text);
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+*/
+
+static char Text_clear_doc[] =
+"() - clear the text buffer";
+
+static PyObject *Text_clear(PyObject *self, PyObject *args)
+{
+ Text *text = PYBLOCK_AS_TEXT(self);
+ int oldstate;
+ CHECK_VALIDTEXT(text)
+
+ oldstate = txt_get_undostate();
+ txt_set_undostate(OFF);
+ txt_sel_all(text);
+ txt_cut_sel(text);
+ txt_set_undostate(oldstate);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static char Text_set_doc[] =
+"(name, val) - set attribute name to val";
+
+static PyObject *Text_set(PyObject *self, PyObject *args)
+{
+ int ival;
+ char *attr;
+ Text *text = PYBLOCK_AS_TEXT(self);
+
+ BPY_TRY(PyArg_ParseTuple(args, "si", &attr, &ival));
+ if (STREQ("follow_cursor", attr)) {
+ if (ival) {
+ text->flags |= TXT_FOLLOW;
+ } else {
+ text->flags &= TXT_FOLLOW;
+ }
+ }
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static char Text_write_doc[] =
+"(line) - append string 'line' to the text buffer";
+
+static PyObject *Text_write(PyObject *self, PyObject *args)
+{
+ char *str;
+ Text *text = PYBLOCK_AS_TEXT(self);
+ int oldstate;
+
+ CHECK_VALIDTEXT(text)
+
+ BPY_TRY(PyArg_ParseTuple(args, "s", &str));
+ oldstate = txt_get_undostate();
+ txt_insert_buf(text, str);
+ txt_move_eof(text, 0);
+ txt_set_undostate(oldstate);
+
+ Py_INCREF(Py_None);
+ return Py_None;
+}
+
+static char Text_asLines_doc[] =
+"() - returns the lines of the text buffer as list of strings";
+
+static PyObject *Text_asLines(PyObject *self, PyObject *args)
+{
+ TextLine *line;
+ PyObject *list, *ob;
+ Text *text = (Text *) ((DataBlock *) self)->data;
+
+ CHECK_VALIDTEXT(text)
+
+ line = text->lines.first;
+ list= PyList_New(0);
+ while (line) {
+ ob = Py_BuildValue("s", line->line);
+ PyList_Append(list, ob);
+ line = line->next;
+ }
+ return list;
+}
+
+/* these are the text object methods */
+struct PyMethodDef Text_methods[] = {
+ {"clear", Text_clear, METH_VARARGS, Text_clear_doc},
+ {"write", Text_write, METH_VARARGS, Text_write_doc},
+ {"set", Text_set, METH_VARARGS, Text_set_doc},
+ {"asLines", Text_asLines, METH_VARARGS, Text_asLines_doc},
+ {NULL, NULL}
+};
+
diff --git a/source/blender/bpython/intern/BPY_tools.c b/source/blender/bpython/intern/BPY_tools.c
new file mode 100644
index 00000000000..5a2c483607c
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_tools.c
@@ -0,0 +1,106 @@
+/* python API tool subroutines
+ * $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 "BKE_global.h"
+#include "BPY_tools.h"
+
+/* These should all have BPY prefixes later on */
+
+PyObject *BPY_incr_ret(PyObject *ob) {
+ Py_INCREF(ob);
+ return ob;
+}
+
+PyObject *BPY_err_ret_ob(PyObject *type, char *err) {
+ PyErr_SetString(type, err);
+ return NULL;
+}
+
+int py_err_ret_int(PyObject *type, char *err) {
+ PyErr_SetString(type, err);
+ return -1;
+}
+
+int BPY_check_sequence_consistency(PyObject *seq, PyTypeObject *against)
+{
+ PyObject *ob;
+ int len= PySequence_Length(seq);
+ int i;
+
+ for (i=0; i<len; i++) {
+ ob= PySequence_GetItem(seq, i);
+ if (ob->ob_type != against) {
+ Py_DECREF(ob);
+ return 0;
+ }
+ Py_DECREF(ob);
+ }
+ return 1;
+}
+
+int BPY_parsefloatvector(PyObject *vec, float *ptr, int n)
+{
+ int i;
+ PyObject *o, *p;
+ char errstring[80];
+
+ if (PyArg_ParseTuple(vec, "ff|f", &ptr[0], &ptr[1], &ptr[2]))
+ return 0;
+ if (PyArg_Parse(vec, "O", &p)) {
+ if (PySequence_Check(p) && PySequence_Length(p) == n ) {
+ for (i = 0; i < n; i++) {
+ o = PySequence_GetItem(vec, i);
+ if (PyFloat_Check(o)) {
+ ptr[i] = PyFloat_AsDouble(o);
+ Py_DECREF(o);
+ } else {
+ Py_DECREF(o);
+ return py_err_ret_int(PyExc_AttributeError, "vector assignment wants floats");
+ }
+ }
+ return 0;
+ }
+ }
+
+ if (!PySequence_Check(p)) {
+ printf("invalid sequence");
+ }
+
+ /* errors: */
+ sprintf(errstring, "Float vector tuple of length %d expected", n);
+ return py_err_ret_int(PyExc_AttributeError, errstring);
+}
+
+
+
+
diff --git a/source/blender/bpython/intern/BPY_tools.h b/source/blender/bpython/intern/BPY_tools.h
new file mode 100644
index 00000000000..902c15686f0
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_tools.h
@@ -0,0 +1,37 @@
+/**
+ * $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 *****
+ */
+/* tools.c */
+extern PyObject *BPY_incr_ret (PyObject *ob);
+extern PyObject *BPY_err_ret_ob (PyObject *type, char *err);
+extern int py_err_ret_int (PyObject *type, char *err);
+extern int BPY_check_sequence_consistency (PyObject *seq, PyTypeObject *against);
+extern int BPY_parsefloatvector(PyObject *vec, float *ptr, int n);
diff --git a/source/blender/bpython/intern/BPY_types.h b/source/blender/bpython/intern/BPY_types.h
new file mode 100644
index 00000000000..217275f6e10
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_types.h
@@ -0,0 +1,39 @@
+/* $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 *****
+ * API defined Object types
+ */
+
+extern PyTypeObject PyIpoCurve_Type, PyBezTriple_Type;
+extern PyTypeObject Button_Type, Buffer_Type;
+extern PyTypeObject NMesh_Type, NMFace_Type, NMVert_Type, NMCol_Type;
+extern PyTypeObject Vector_Type, Matrix_Type;
+
+extern PyTypeObject DataBlock_Type;
+extern struct PyMethodDef Null_methods[];
diff --git a/source/blender/bpython/intern/BPY_window.h b/source/blender/bpython/intern/BPY_window.h
new file mode 100644
index 00000000000..7a76dbd2e57
--- /dev/null
+++ b/source/blender/bpython/intern/BPY_window.h
@@ -0,0 +1,33 @@
+/**
+ * $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 *****
+ */
+void window_update_curCamera(Object *camera);
+
diff --git a/source/blender/bpython/intern/Makefile b/source/blender/bpython/intern/Makefile
new file mode 100644
index 00000000000..cb67e195aa8
--- /dev/null
+++ b/source/blender/bpython/intern/Makefile
@@ -0,0 +1,75 @@
+#
+# $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 *****
+#
+#
+
+LIBNAME = bpython
+DIR = $(OCGDIR)/blender/$(LIBNAME)
+
+include nan_compile.mk
+
+ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows"))
+ CFLAGS += -funsigned-char
+endif
+
+CFLAGS += $(LEVEL_1_C_WARNINGS)
+
+CPPFLAGS += -DFUTURE_PYTHON_API # see api.h for configuration
+#CPPFLAGS += -DNO_RELEASE # see api.h for configuration
+
+# OpenGL and Python
+CPPFLAGS += -I$(OPENGL_HEADERS)
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+CPPFLAGS += -I$(NAN_BMFONT)/include/
+
+# Reference to the types in makesdna and imbuf
+CPPFLAGS += -I../../makesdna
+CPPFLAGS += -I../../imbuf
+# This mod uses the BLI and BLO module
+CPPFLAGS += -I../../blenlib
+CPPFLAGS += -I../../blenlib/intern
+CPPFLAGS += -I$(NAN_BSP)/include # BSP includes
+CPPFLAGS += -I../../blenkernel
+CPPFLAGS += -I../../blenloader
+CPPFLAGS += -I../../bpython/include/
+# also avi is used
+CPPFLAGS += -I../../avi
+CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+
+# we still refer to /include a bit...
+CPPFLAGS += -I../../include
+
+# to include the render stuff:
+CPPFLAGS += -I../../render/extern/include
+
+# path to our own external headerfiles
+CPPFLAGS += -I..
+
diff --git a/source/blender/bpython/intern/README b/source/blender/bpython/intern/README
new file mode 100644
index 00000000000..c91e284cd27
--- /dev/null
+++ b/source/blender/bpython/intern/README
@@ -0,0 +1,22 @@
+Python API library // strubi@blender.nl
+------------------
+
+
+NEW:
+ Several frozen Python byte code modules are now included in the
+ API under libfrozen.a. libbpython must be linked with libfrozen.a
+ from now on.
+
+source files:
+
+py_*.c: library files of Jan Walters API. Might undergo major replacements / surgery
+ later.
+opy_*: the 'old' python API code. In fact quite nice and functional... -- needs
+ splitting up in API/ interfacing part.
+BPY_*: these are the future API prefixes (newly written stuff that should be
+ Blender 3.0 compliant... -- no interface calls inside)
+ This is not YET quite true, for convenience, it still contains some direct
+ Blender access.
+b_* : Blender interfacing / tools -- may contain dirty access hacks for blender
+ datastructures..
+
diff --git a/source/blender/bpython/intern/api.h b/source/blender/bpython/intern/api.h
new file mode 100644
index 00000000000..369e6175918
--- /dev/null
+++ b/source/blender/bpython/intern/api.h
@@ -0,0 +1,87 @@
+/* $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 headerfile defines the API status.
+ * Parts of the API can be compiled as dynamic module for testing --
+ * see Makefile
+ */
+
+#undef EXPERIMENTAL /* undefine this for release, please :-) */
+
+/* Uncomment this if you want to have the new blender module
+compiled static into Blender :*/
+/* #define SHAREDMODULE -- put into Makefile */
+
+/* API configuration -- define in Makefile */
+
+#ifdef SHAREDMODULE
+ #define BLENDERMODULE _Blender
+#elif defined(CURRENT_PYTHON_API)
+ #define BLENDERMODULE Blender
+#elif defined(FUTURE_PYTHON_API)
+ #define BLENDERMODULE _Blender
+#else // FALLBACK
+ #define BLENDERMODULE Blender
+#endif
+
+#define SUBMODULE(mod) (MODNAME(BLENDERMODULE) "." #mod)
+
+/* this macro defines the init routine for dynamically loaded modules;
+example:
+
+void INITMODULE(BLENDERMODULE) -> void initBlender(void)
+*/
+
+#define _INITMODULE(x) init##x
+#define INITMODULE(x) _INITMODULE(x)
+
+/* MODNAME(MODULE) stringifies the module definition, example:
+MODNAME(BLENDERMODULE) -> "_Blender"
+*/
+
+#define _MODNAME(x) #x
+#define MODNAME(x) _MODNAME(x)
+
+// module configuration -- TODO: this should be set later from the Makefile...
+#if defined(__FreeBSD__) || defined(__linux__) || defined (__sgi) || defined(__sparc)
+#define STATIC_TEXTTOOLS 1
+#endif
+
+
+#define USE_NMESH 1 // still use NMesh structure for <mesh object>.data
+#define CLEAR_NAMESPACE // undefine this if you still want the old dirty global
+ // namespace shared by ALL scripts.
+
+
+// experimental sh*t:
+#ifdef EXPERIMENTAL
+ #undef USE_NMESH
+#endif
diff --git a/source/blender/bpython/intern/b_import.c b/source/blender/bpython/intern/b_import.c
new file mode 100644
index 00000000000..e490ee82338
--- /dev/null
+++ b/source/blender/bpython/intern/b_import.c
@@ -0,0 +1,191 @@
+/* $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 *****
+
+ Customized Blender import module, Sandbox model (TODO)
+
+ TODO for Sandbox:
+ - only allow builtin modules to be imported
+ - only allow file read/write from certain directories
+ - alternative: override file read/write with popup requester
+
+ main routine:
+ init_ourImport();
+
+*/
+
+
+
+#include "DNA_text_types.h"
+#include "Python.h"
+#include "import.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_library.h"
+#include "BKE_text.h"
+
+#include "BLI_blenlib.h" // mallocs
+
+#include "BPY_macros.h"
+#include "BPY_main.h"
+
+#include "b_import.h"
+
+
+/* ---------------------------------------------------------------------------- */
+
+PyObject *importText(char *name)
+{
+ Text *text;
+ char txtname[IDNAME];
+ char *buf = NULL;
+
+
+ // TODO debug for too long names !
+
+ strncpy(txtname, name, IDNAME-4);
+ strcat(txtname, ".py");
+
+ text = (Text*) getGlobal()->main->text.first;
+ while(text)
+ {
+ if (STREQ(getName(text), txtname))
+ break;
+ text = text->id.next;
+ }
+ if (!text) {
+ return NULL;
+ }
+
+ if (!text->compiled) {
+ buf = txt_to_buf(text);
+ text->compiled = Py_CompileString(buf, getName(text), Py_file_input);
+ MEM_freeN(buf);
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ BPY_free_compiled_text(text);
+ return NULL;
+ }
+ }
+ BPY_debug(("import from TextBuffer: %s\n", txtname));
+ return PyImport_ExecCodeModule(name, text->compiled);
+}
+
+PyObject *blender_import(PyObject *self, PyObject *args)
+{
+ PyObject *exception, *err, *tb;
+ char *name;
+ PyObject *globals = NULL, *locals = NULL, *fromlist = NULL;
+ PyObject *m;
+#ifdef PY_SANDBOXTEST
+ PyObject *l, *n;
+#endif
+
+ if (!PyArg_ParseTuple(args, "s|OOO:bimport",
+ &name, &globals, &locals, &fromlist))
+ return NULL;
+
+#ifdef PY_SANDBOXTEST
+ /* check for builtin modules */
+ m = PyImport_AddModule("sys");
+ l = PyObject_GetAttrString(m, "builtin_module_names");
+ n = PyString_FromString(name);
+
+ if (PySequence_Contains(l, n)) {
+ Py_DECREF(l);
+ m = PyImport_ImportModuleEx(name, globals, locals, fromlist);
+ return m;
+ } else {
+ /* TODO check for external python toolbox modules */
+
+ PyErr_Format(PyExc_ImportError,
+ "Import of external Module %.40s not allowed.\n\
+Please disable security in the UserButtons", name);
+ Py_DECREF(l);
+ return NULL;
+ }
+
+#else
+ m = PyImport_ImportModuleEx(name, globals, locals, fromlist);
+ if (m)
+ return m;
+ else
+ PyErr_Fetch(&exception, &err, &tb); // restore exception for probable later use
+
+ m = importText(name);
+ if (m) { // found module, ignore above exception
+ PyErr_Clear();
+ Py_XDECREF(exception); Py_XDECREF(err); Py_XDECREF(tb);
+ printf("imported from text buffer..\n");
+ } else {
+ PyErr_Restore(exception, err, tb);
+ }
+ return m;
+#endif
+}
+static PyMethodDef bimport[] = {
+ { "blimport", blender_import, METH_VARARGS,
+ "our own import"}
+};
+
+
+/*
+PyObject *override_method(PyObject *module, char *methname, PyMethodDef *newcfunc)
+{
+ PyObject *d;
+ PyObject *old;
+ PyObject *pycfunc;
+
+
+ d = PyModule_GetDict(module);
+ old = PyDict_GetItemString(module, methname);
+ if (!old)
+ return NULL;
+
+ pycfunc = PyCFunction_New(newcfunc, NULL);
+ PyDict_SetItemString(d, methname, pycfunc);
+
+ return old;
+}
+*/
+
+
+/* this overrides the built in __import__ function
+with our customized importer */
+void init_ourImport(void)
+{
+ PyObject *m, *d;
+ PyObject *import = PyCFunction_New(bimport, NULL);
+
+ m = PyImport_AddModule("__builtin__");
+ d = PyModule_GetDict(m);
+ PyDict_SetItemString(d, "__import__", import);
+}
+
diff --git a/source/blender/bpython/intern/b_import.h b/source/blender/bpython/intern/b_import.h
new file mode 100644
index 00000000000..2bc191942ca
--- /dev/null
+++ b/source/blender/bpython/intern/b_import.h
@@ -0,0 +1,35 @@
+/**
+ * $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 *****
+ */
+/* b_import.c */
+PyObject *importText (char *name);
+PyObject *blender_import (PyObject *self, PyObject *args);
+void init_ourImport (void);
diff --git a/source/blender/bpython/intern/b_interface.c b/source/blender/bpython/intern/b_interface.c
new file mode 100644
index 00000000000..ec89680ad91
--- /dev/null
+++ b/source/blender/bpython/intern/b_interface.c
@@ -0,0 +1,753 @@
+/** Interfacing with Blender
+ *
+ * ***** 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 *****
+ *
+ * $Id$
+ *
+ * This code is currently messy and an attempt to restructure
+ * some Blender kernel level code.
+ * Hopefully a template for a future C-API...
+ *
+ *
+ */
+
+
+#include "BLI_blenlib.h" // mallocs
+#include "BLI_arithb.h"
+
+#include "BKE_library.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_object.h"
+#include "BKE_mesh.h"
+#include "BKE_ipo.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "Python.h"
+#include "BPY_macros.h"
+#include "structmember.h"
+
+#include "BDR_editobject.h"
+
+#include "b_interface.h"
+
+/************************************************************************
+ * Generic low level routines
+ *
+ */
+
+/** This just returns a pointer to the global struct.
+ *
+ * Mainly introduced for debugging purposes..
+ *
+ */
+
+Global *getGlobal(void)
+{
+ return &G;
+}
+
+/** define list getters:
+ These functions return a linked list pointer (ListBase *) from the global
+ Blender-object list.
+
+ Example:
+ oblist = getObjectList();
+ firstobject = oblist->first;
+
+ */
+
+/*
+DEF_GETLIST(Scene, scene)
+DEF_GETLIST(Object, object)
+DEF_GETLIST(Mesh, mesh)
+DEF_GETLIST(Camera, camera)
+DEF_GETLIST(Material, mat)
+DEF_GETLIST(Lamp, lamp)
+DEF_GETLIST(World, world)
+DEF_GETLIST(Ipo, ipo)
+DEF_GETLIST(Image, image)
+DEF_GETLIST(Texture, tex)
+DEF_GETLIST(Text, text)
+DEF_GETLIST(Key, key)
+*/
+
+/* gets a datablock object from the ID list by name */
+ID *getFromList(ListBase *list, char *name)
+{
+ ID *id = list->first;
+
+ while (id) {
+ if(STREQ(name, getIDName(id))) break;
+ id= id->next;
+ }
+ return id;
+}
+
+void printList(ListBase *list)
+{
+ ID *walk = list->first;
+ ID *lastwalk = 0;
+ printf("List: %s\n", walk->name);
+ while (walk) {
+ printf(" %s\n", walk->name);
+ lastwalk = walk;
+ walk= walk->next;
+ }
+ if (list->last != lastwalk)
+ {
+ printf("****: listbase->last pointing to wrong end!\n");
+ // list->last = lastwalk;
+ }
+}
+
+
+/** (future) garbage collector subroutine */
+
+
+int gc_mainlist(ListBase *lb)
+{
+ ID *id = (ID *) lb->first;
+
+ while (id) {
+ if (getIDUsers(id) == 0) {
+ switch(GET_ID_TYPE(id)) {
+ case ID_OB:
+ BPY_debug(("free [Object %s]\n", getIDName(id)));
+ unlink_object((Object *) id);
+ free_libblock(lb, id);
+ break;
+ default: break;
+ }
+ }
+ id = id->next;
+ }
+ return 1;
+}
+
+ /** Garbage collection function. EXPERIMENTAL!
+ * This should free Blender from all unreferenced Objects (i.e.
+ * user count == 0).
+ * Don't expect too much yet -- User counting isn't done
+ * consequently in Blender. Neither parenting or bevelcurves
+ * etc. respect user counts...therefore, no circular references
+ * show up -- which are in fact possible; example:
+ *
+ * A BevelCurve is parenting its BevelObject: so there is a
+ * reference from the BevelObject to the BevelCurve, and a
+ * reference back from the Bevelcurve to the BevelObject.
+ *
+ * There are a lot of cleanup functions in Blender taking care
+ * of updating (invalidating) references to deleted objects.
+ * See unlink_object() for more details.
+ *
+ * This function must not be called inside a script, so don't go
+ * and create a wrapper for it :-)
+ * In a hopefully later implementation, the Python garbage collection
+ * might be used. For the moment, this is better than 'Save and Reload'
+ */
+
+ int garbage_collect(Main *m)
+ {
+ /* Remember, all descriptor objects must BOB_DECUSER on their raw
+ Blender Datablock in their __del__ method (C-API: dealloc function) */
+
+ gc_mainlist(&m->object);
+
+ /* TODO proper kernel level functions for safely freeing these objects
+ * must first be implemented...
+ gc_mainlist(&m->mesh);
+ gc_mainlist(&m->mat);
+ gc_mainlist(&m->lamp);
+ gc_mainlist(&m->camera);
+
+ .. and this list is far from being complete.
+ */
+
+ return 1;
+}
+
+/** expands pointer array of length 'oldsize' to length 'newsize'.
+ * A pointer to the (void *) array must be passed as first argument
+ * The array pointer content can be NULL, in this case a new array of length
+ * 'newsize' is created.
+ */
+
+static int expandPtrArray(void **p, int oldsize, int newsize)
+{
+ void *newarray;
+
+ if (newsize < oldsize) {
+ return 0;
+ }
+ newarray = MEM_callocN(newsize * sizeof(void *), "PtrArray");
+ if (*p) {
+ memcpy(newarray, *p, oldsize);
+ MEM_freeN(*p);
+ }
+ *p = newarray;
+ return 1;
+}
+
+/************************************************************************
+ * Material object low level routines
+ *
+ */
+
+/* MAXMAT = maximum number of materials per object/ object data */
+
+#define MATINDEX_CHECK(x) \
+ if ((x) < 0 || (x) >= MAXMAT) { printf("illegal matindex!\n"); return 0; }
+
+/** Returns a new material list (material pointer array) of length 'len'
+ *
+ */
+
+Material **newMaterialList(int len)
+{
+ Material **matlist =
+ (Material **) MEM_mallocN(len * sizeof(Material *), "MaterialList");
+ return matlist;
+}
+
+/** releases material list and decrements user count on materials */
+
+int releaseMaterialList(Material **matlist, int len)
+{
+ int i;
+ Material *m;
+
+ MATINDEX_CHECK(len);
+
+ for (i= 0; i < len; i++) {
+
+ m = matlist[i];
+ BOB_XDECUSER((ID *) m);
+ }
+ MEM_freeN(matlist);
+ return 1;
+}
+
+/** Synchronizes Object <-> data material lists. Blender just wants it. */
+
+int synchronizeMaterialLists(Object *object, void *data)
+{
+ // get pointer to data's material array:
+ // and number of data materials
+ // ... because they will need modification.
+
+ Material ***p_dataMaterials = give_matarar(object);
+ short *nmaterials = give_totcolp(object);
+
+ if (object->totcol > *nmaterials){ // more object mats than data mats
+ *nmaterials = object->totcol;
+ return expandPtrArray((void *) p_dataMaterials, *nmaterials, object->totcol);
+ } else if (object->totcol < *nmaterials) {
+ object->totcol = *nmaterials;
+ return expandPtrArray((void *) &object->mat, object->totcol, *nmaterials);
+ }
+ return 1; // in this case, no synchronization needed; they're of equal
+ // length
+}
+
+/************************************************************************
+ * Object low level routines
+ *
+ */
+
+/** creates a new empty object of type OB_ (TODO: should be enum)
+ *
+ */
+
+
+Object *object_new(int type)
+{
+ Object *object;
+ char name[32];
+
+ Global *g = getGlobal();
+
+ switch(type) {
+ case OB_MESH: strcpy(name, "Mesh"); break;
+ case OB_CURVE: strcpy(name, "Curve"); break;
+ case OB_SURF: strcpy(name, "Surf"); break;
+ case OB_FONT: strcpy(name, "Text"); break;
+ case OB_MBALL: strcpy(name, "Mball"); break;
+ case OB_CAMERA: strcpy(name, "Camera"); break;
+ case OB_LAMP: strcpy(name, "Lamp"); break;
+ case OB_IKA: strcpy(name, "Ika"); break;
+ case OB_LATTICE: strcpy(name, "Lattice"); break;
+ case OB_WAVE: strcpy(name, "Wave"); break;
+ case OB_ARMATURE: strcpy(name,"Armature");break;
+ default: strcpy(name, "Empty");
+ }
+
+ object = alloc_libblock(getObjectList(), ID_OB, name);
+
+ /* user count is set to 1 by alloc_libblock, we just reset it to 0... */
+ BOB_USERCOUNT((ID*) object) = 0; // it's a new object, so no user yet
+ object->flag = 0;
+ object->type = type;
+
+ /* transforms */
+ QuatOne(object->quat);
+ QuatOne(object->dquat);
+
+ object->col[3]= 1.0; // alpha
+
+ object->size[0] = object->size[1] = object->size[2] = 1.0;
+ object->loc[0] = object->loc[1] = object->loc[2] = 0.0;
+ Mat4One(object->parentinv);
+ Mat4One(object->obmat);
+ object->dt = OB_SHADED; // drawtype
+
+ object_setdefaults(object);
+
+ object->lay = 1; // Layer, by default visible
+
+ switch(type) {
+ case OB_MESH: object->data= add_mesh(); g->totmesh++; break;
+ case OB_CAMERA: object->data= add_camera(); break;
+ case OB_LAMP: object->data= add_lamp(); g->totlamp++; break;
+
+ // TODO the following types will be supported later
+ // case OB_CURVE: object->data= add_curve(OB_CURVE); g->totcurve++; break;
+ // case OB_SURF: object->data= add_curve(OB_SURF); g->totcurve++; break;
+ // case OB_FONT: object->data= add_curve(OB_FONT); break;
+ // case OB_MBALL: object->data= add_mball(); break;
+ // case OB_IKA: object->data= add_ika(); object->dt= OB_WIRE; break;
+ // case OB_LATTICE: object->data= (void *)add_lattice(); object->dt= OB_WIRE; break;
+ // case OB_WAVE: object->data= add_wave(); break;
+ // case OB_ARMATURE: object->data=add_armature();break;
+ }
+
+ g->totobj++; // gee, I *hate* G
+ return object;
+}
+
+/* returns new Base */
+Base *object_newBase(Object *object)
+{
+ Base *base;
+ base = MEM_callocN(sizeof(Base), "newbase");
+ if (!base)
+ return 0;
+ base->object = object;
+ base->lay = object->lay;
+ base->flag = object->flag;
+ return base;
+}
+
+Object *object_copy(Object *object)
+{
+ Object *new;
+
+ new = copy_object(object);
+ BOB_USERCOUNT((ID*) new) = 0; // it's a new object, so no user yet
+ return new;
+}
+
+/* Set draw mode of object */
+void object_setDrawMode(Object *object, int modebits)
+{
+ object->dt = (modebits & 0xff);
+ object->dtx = (modebits >> 8);
+}
+
+int object_getDrawMode(Object *object)
+{
+ return (((int) object->dtx) << 8 ) + object->dt;
+}
+
+/* link data to Object object */
+int object_linkdata(Object *object, void *data)
+{
+ ID *oldid, *id;
+ int valid;
+
+ if (!data) return 0;
+
+ oldid = (ID*) object->data;
+ id = (ID*) data;
+
+ valid = 0;
+
+#define _CASE(objtype, idtype) \
+ case objtype:\
+ if (GET_ID_TYPE(id) == idtype) \
+ valid = 1; \
+ break;
+
+ switch (object->type) {
+ _CASE(OB_MESH, ID_ME)
+ _CASE(OB_CAMERA, ID_CA)
+ _CASE(OB_LAMP, ID_LA)
+ default: // not supported
+ return 0;
+ }
+ if (valid) {
+ object->data = data;
+ BOB_INCUSER(id);
+ if (oldid)
+ BOB_DECUSER(oldid); // dec users
+
+ // extra check for multi materials on meshes:
+ // This is a hack to check whether object material lists are of same
+ // length as their data material lists..
+ //if (GET_ID_TYPE(id) == ID_ME) {
+ //test_object_materials(id);
+ //}
+ return 1;
+ }
+ return 0;
+}
+
+/* release data from object object */
+
+int object_unlinkdata(Object *object)
+{
+ ID *id = object->data;
+
+ BOB_XDECUSER(id);
+ return 1;
+}
+
+/** set Object materials:
+ * takes a list of Material pointers of maximum length MAXMAT
+ */
+
+int object_setMaterials(Object *object, Material **matlist, int len)
+{
+ int i;
+
+ MATINDEX_CHECK(len)
+ if (object->mat) {
+ releaseMaterialList(object->mat, len);
+ }
+ // inc user count on all materials
+ for (i = 0; i < len; i++) {
+ BOB_XINCUSER( (ID *) matlist[i]);
+ }
+
+ object->mat = matlist;
+ object->totcol = len;
+ object->actcol = len - 1; // XXX
+ // workaround: blender wants the object's data material list
+ // to be of the same length, otherwise colourful fun happens.
+ // so, we synchronize this here:
+
+ switch (object->type)
+ {
+ case OB_MESH:
+ case OB_CURVE:
+ case OB_FONT:
+ case OB_SURF:
+ case OB_MBALL:
+ synchronizeMaterialLists(object, object->data);
+ break;
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+/** make 'object' the parent of the object 'child'
+ *
+ * mode = 1: set parent inverse matrix to _1_ ('clear inverse')
+ * fast = 1: Don't update scene base (hierarchy). In this case,
+ * sort_baselist() needs to be called explicitely before redraw.
+ */
+
+int object_makeParent(Object *parent, Object *child, int mode, int fast)
+{
+ if (test_parent_loop(parent, child)) {
+ PyErr_SetString(PyExc_RuntimeError, "parenting loop detected!");
+ return 0;
+ }
+ child->partype = PAROBJECT;
+ child->parent = parent;
+ if (mode == 1) {
+ Mat4One(child->parentinv); // parent inverse = unity
+ child->loc[0] = 0.0; child->loc[1] = 0.0; child->loc[2] = 0.0;
+ } else {
+ what_does_parent(child);
+ Mat4Invert(child->parentinv, parent->obmat); // save inverse
+ }
+
+ /* This is some bad global thing again -- we should determine
+ the current scene
+ another way. Later. */
+ if (!fast)
+ sort_baselist(getGlobal()->scene);
+
+ return 1;
+}
+
+/** Unlink parenting hierarchy:
+ *
+ * mode = 2: keep transform
+ * fast = 1: don't update scene bases. see makeParent()
+ */
+
+int object_clrParent(Object *child, int mode, int fast)
+{
+ Object *par;
+
+ par = child->parent;
+ child->parent = 0;
+ if (mode == 2) { // keep transform
+ apply_obmat(child);
+ }
+ if (!fast)
+ sort_baselist(getGlobal()->scene);
+ return 1;
+}
+
+/** Set object's defaults */
+
+int object_setdefaults(Object *ob)
+{
+ if(U.flag & MAT_ON_OB) ob->colbits= -1;
+ switch(ob->type) {
+ case OB_CAMERA:
+ case OB_LAMP:
+ ob->trackflag = OB_NEGZ;
+ ob->upflag = OB_POSY;
+ break;
+ default:
+ ob->trackflag = OB_POSY;
+ ob->upflag = OB_POSZ;
+ }
+ ob->ipoflag = OB_OFFS_OB + OB_OFFS_PARENT;
+
+ /* duplivert settings */
+
+ ob->dupon = 1; ob->dupoff = 0;
+ ob->dupsta = 1; ob->dupend = 100;
+
+ /* Gameengine defaults*/
+ ob->mass= ob->inertia= 1.0;
+ ob->formfactor= 0.4;
+ ob->damping= 0.04;
+ ob->rdamping= 0.1;
+ ob->anisotropicFriction[0] = 1.0;
+ ob->anisotropicFriction[1] = 1.0;
+ ob->anisotropicFriction[2] = 1.0;
+
+ /* default to not use fh in new system */
+ ob->gameflag= OB_PROP; /*|OB_DO_FH; */
+
+ return 1;
+}
+
+/************************************************************************
+ * Creation of new data blocks
+ *
+ * We [ab|re]use the blender kernel functions, but set the user count to 0,
+ * because the object does not have users yet.
+ * Currently, the user count is abused as reference count which should be
+ * separate in future
+ */
+
+Material *material_new(void)
+{
+ Material *m = add_material("Material");
+ BOB_USERCOUNT((ID*) m) = 0; // set 'refcount' to 0, because
+ // it's a free material
+ return m;
+}
+
+Lamp *lamp_new()
+{
+ Lamp *la;
+
+ la = add_lamp();
+ BOB_USERCOUNT((ID*) la) = 0;
+
+ return la;
+}
+
+Camera *camera_new()
+{
+ Camera *cam;
+
+ cam = add_camera();
+ BOB_USERCOUNT((ID*) cam) = 0;
+ return cam;
+}
+
+Ipo *ipo_new(int type, char *name)
+{
+ Ipo *ipo;
+
+ ipo = add_ipo(name, type);
+ BOB_USERCOUNT((ID*) ipo) = 0;
+ return ipo;
+}
+
+
+/* Finds the ipo curve with channel code 'code' in the datablock 'ipo'
+ and returns it, if found (NULL otherwise) */
+
+IpoCurve *ipo_findcurve(Ipo *ipo, int code)
+{
+ IpoCurve *ipocurve;
+
+ ipocurve = ipo->curve.first;
+ while(ipocurve) {
+ if (ipocurve->adrcode == code) break;
+ ipocurve = ipocurve->next;
+ }
+ return ipocurve;
+}
+
+
+/** Returns a new Ipo curve */
+IpoCurve *ipocurve_new()
+{
+ IpoCurve *curve;
+
+ curve = MEM_callocN(sizeof(IpoCurve), "new_ipocurve");
+ curve->flag = IPO_VISIBLE;
+ return curve;
+}
+
+IpoCurve *ipocurve_copy(IpoCurve *curve)
+{
+ IpoCurve *newcurve;
+
+ newcurve = MEM_callocN(sizeof(IpoCurve), "new_ipocurve");
+ memcpy(newcurve, curve, sizeof(IpoCurve));
+ // copy bez triples:
+ newcurve->bezt= MEM_mallocN(curve->totvert*sizeof(BezTriple), "ipocurve_copy");
+ memcpy(newcurve->bezt, curve->bezt, curve->totvert*sizeof(BezTriple));
+ return newcurve;
+}
+
+/** Assign ipo to object object */
+
+/* macros, see b_interface.h */
+
+DEF_ASSIGN_IPO(object, Object) // defines object_assignIpo()
+
+DEF_ASSIGN_IPO(camera, Camera)
+
+DEF_ASSIGN_IPO(lamp, Lamp)
+
+DEF_ASSIGN_IPO(material, Material)
+
+/************************************************************************
+ * Mesh object low level routines
+ *
+ */
+
+/** Returns a new, free (non owned) mesh.
+ * add_mesh() automatically returns a mesh object with users = 1,
+ * so we set it to 0. Hack, hack.
+ */
+
+Mesh *mesh_new(void)
+{
+ Mesh *me = add_mesh();
+ ((ID *) me)->us = 0;
+ return me;
+}
+
+/** updates drawing properties etc. of mesh */
+
+void mesh_update(Mesh *mesh)
+{
+ edge_drawflags_mesh(mesh);
+ tex_space_mesh(mesh);
+}
+
+/************************************************************************
+ * Scene object low level routines
+ *
+ */
+
+/** Returns current Scene */
+
+Scene *scene_getCurrent(void)
+{
+ return getGlobal()->scene;
+}
+
+/* returns base of object 'object' in Scene 'scene', 0 if nonexistant
+ * A base is basically an visual instantiation of an 3D object (Object)
+ * in a Scene. See scene_linkObject()
+ *
+ */
+
+Base *scene_getObjectBase(Scene *scene, Object *object)
+{
+ Base *base;
+ base = scene->base.first;
+ while (base)
+ {
+ if (object == base->object) // it exists
+ return base;
+ base = base->next;
+ }
+ return NULL;
+}
+
+/* links an object into a scene */
+int scene_linkObject(Scene *scene, Object *object)
+{
+ Base *base, *b;
+ b = scene_getObjectBase(scene, object);
+ if (b)
+ return 0;
+ base = object_newBase(object);
+ if (!base) {
+ return 0;
+ }
+ BOB_INCUSER((ID *) object); // incref the object
+ BLI_addhead(&scene->base, base);
+ return 1;
+}
+
+/* unlinks an object from a scene */
+int scene_unlinkObject(Scene *scene, Object *object)
+{
+ Base *base;
+ base = scene_getObjectBase(scene, object);
+ if (base) {
+ BLI_remlink(&scene->base, base);
+ BOB_DECUSER((ID *) object);
+ MEM_freeN(base);
+ scene->basact = 0; // make sure the just deleted object has no longer an
+ // active base (which happens if it was selected
+ return 1;
+ }
+ else return 0;
+}
+
diff --git a/source/blender/bpython/intern/b_interface.h b/source/blender/bpython/intern/b_interface.h
new file mode 100644
index 00000000000..b2af2280f1f
--- /dev/null
+++ b/source/blender/bpython/intern/b_interface.h
@@ -0,0 +1,184 @@
+/**
+ * $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 "DNA_ID.h"
+#include "DNA_mesh_types.h"
+#include "DNA_view3d_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
+#include "DNA_text_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_camera_types.h"
+#include "DNA_ipo_types.h"
+#include "DNA_image_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_material_types.h"
+#include "DNA_scriptlink_types.h"
+#include "DNA_userdef_types.h" /* for userdata struct; U.pythondir */
+
+#include "BKE_main.h"
+#include "BKE_material.h"
+#include "BKE_mesh.h"
+#include "BKE_object.h"
+#include "BKE_scene.h"
+#include "BKE_global.h"
+
+/* DEFINES */
+
+#define ASSIGN_IPO(prefix, type) \
+ prefix##_assignIpo(type *obj, Ipo *ipo)
+
+// example DEF_ASSIGN_IPO(Object, obj) ->
+// int object_assignIpo(Object *obj, Ipo *ipo)
+
+#define DEF_ASSIGN_IPO(prefix, type) \
+ int prefix##_assignIpo(type *obj, Ipo *ipo) \
+ { \
+ BOB_XDECUSER((ID*) obj->ipo); \
+ BOB_XINCUSER((ID*) ipo); \
+ obj->ipo = ipo; \
+ return 1; \
+ } \
+
+// defined prototypes:
+
+#define FUNC_ASSIGN_IPO(prefix, arg1, arg2) \
+ prefix##_assignIpo(arg1, arg2)
+
+#define object_assignIpo(arg1, arg2) FUNC_ASSIGN_IPO(object, arg1, arg2)
+#define material_assignIpo(arg1, arg2) FUNC_ASSIGN_IPO(material, arg1, arg2)
+#define camera_assignIpo(arg1, arg2) FUNC_ASSIGN_IPO(camera, arg1, arg2)
+#define lamp_assignIpo(arg1, arg2) FUNC_ASSIGN_IPO(lamp, arg1, arg2)
+
+/** Defines for List getters */
+
+/*
+#define PROTO_GETLIST(name, member) \
+ ListBase *get##name##List(void)
+
+#define DEF_GETLIST(name, member) \
+ PROTO_GETLIST(name, member) \
+ { \
+ return &(G.main->member); \
+ }
+*/
+
+/* PROTOS */
+
+#define _GETMAINLIST(x) \
+ (&(G.main->x))
+
+#define getSceneList() _GETMAINLIST(scene)
+#define getObjectList() _GETMAINLIST(object)
+#define getMeshList() _GETMAINLIST(mesh)
+#define getMaterialList() _GETMAINLIST(mat)
+#define getCameraList() _GETMAINLIST(camera)
+#define getLampList() _GETMAINLIST(lamp)
+#define getWorldList() _GETMAINLIST(world)
+#define getIpoList() _GETMAINLIST(ipo)
+#define getImageList() _GETMAINLIST(image)
+#define getTextureList() _GETMAINLIST(tex)
+#define getTextList() _GETMAINLIST(text)
+#define getKeyList() _GETMAINLIST(key)
+#define getLatticeList() _GETMAINLIST(latt)
+
+/*
+PROTO_GETLIST(Scene, scene);
+PROTO_GETLIST(Object, object);
+PROTO_GETLIST(Mesh, mesh);
+PROTO_GETLIST(Camera, camera);
+PROTO_GETLIST(Material, mat);
+PROTO_GETLIST(Lamp, lamp);
+PROTO_GETLIST(World, world);
+PROTO_GETLIST(Ipo, ipo);
+PROTO_GETLIST(Image, image);
+PROTO_GETLIST(Texture, tex);
+PROTO_GETLIST(Text, text);
+PROTO_GETLIST(Key, key); */
+
+
+Global *getGlobal(void); // get Global struct
+
+ID *getFromList(ListBase *list, char *name);
+
+int garbage_collect(Main *m);
+
+
+Material **newMaterialList(int len);
+int releaseMaterialList(struct Material **matlist, int len);
+int synchronizeMaterialLists(Object *object, void *data);
+
+// Datablock management
+
+Material *material_new(void);
+int material_assignIpo(Material *, Ipo *);
+
+Lamp *lamp_new(void);
+int lamp_assignIpo(Lamp *, Ipo *);
+
+Camera *camera_new(void);
+int camera_assignIpo(Camera *, Ipo *);
+
+Ipo *ipo_new(int type, char *name);
+IpoCurve *ipo_findcurve(Ipo *ipo, int code);
+IpoCurve *ipocurve_new(void);
+IpoCurve *ipocurve_copy(IpoCurve *curve);
+
+// Object management
+Base *object_newBase(Object *obj);
+int object_linkdata(Object *obj, void *data);
+int object_unlinkdata(Object *obj);
+int object_setMaterials(Object *object, Material **matlist, int len);
+int object_setdefaults(Object *ob);
+int object_copyMaterialsTo(Object *object, Material **matlist, int len);
+int object_makeParent(Object *parent, Object *child, int noninverse, int fast);
+int object_clrParent(Object *child, int mode, int fast);
+Object *object_new(int type);
+Object *object_copy(Object *obj);
+void object_setDrawMode(Object *object, int val);
+int object_getDrawMode(Object *object);
+
+int object_assignIpo(Object *, Ipo *);
+
+Scene *scene_getCurrent(void);
+int scene_linkObject(Scene *scene, Object *obj);
+int scene_unlinkObject(Scene *scene, Object *object);
+Base *scene_getObjectBase(Scene *scene, Object *object);
+
+Mesh *mesh_new(void);
+void mesh_update(Mesh *me);
+
+/* blender's program name */
+extern char bprogname[]; /* init in creator.c */
+
+
+
diff --git a/source/blender/bpython/intern/opy_blender.c b/source/blender/bpython/intern/opy_blender.c
new file mode 100644
index 00000000000..6bbac3d958e
--- /dev/null
+++ b/source/blender/bpython/intern/opy_blender.c
@@ -0,0 +1,342 @@
+/* python code for Blender, written by Daniel Dunbar */
+/*
+ * $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 "b_interface.h"
+#include "BPY_tools.h"
+#include "BPY_modules.h"
+#include "BPY_main.h"
+
+#include "BKE_main.h"
+#include "BKE_object.h" // during_script() (what is this ?)
+#include "BKE_global.h"
+#include "BKE_ipo.h" // frame_to_float()
+#include "BKE_blender.h"
+
+#include "BIF_space.h" // allqueue()
+#include "BSE_headerbuttons.h"
+
+#include "BPY_types.h" // userdefined Python Objects
+#include <string.h>
+
+#include "DNA_userdef_types.h"
+
+#include "mydevice.h"
+
+//#include "py_blender.h"
+//#include "screen.h"
+//#include "ipo.h"
+
+void INITMODULE(BLENDERMODULE)(void);
+
+PyObject *g_sysmodule;
+
+
+/*
+NamedEnum TextureTypes[]= {
+ {"Clouds", TEX_CLOUDS},
+ {"Wood", TEX_WOOD},
+ {"Marble", TEX_MARBLE},
+ {"Magic", TEX_MAGIC},
+ {"Blend", TEX_BLEND},
+ {"Stucci", TEX_STUCCI},
+ {"Noise", TEX_NOISE},
+ {"Image", TEX_IMAGE},
+ {"Plugin", TEX_PLUGIN},
+ {"Envmap", TEX_ENVMAP},
+ {NULL}
+};
+
+DataBlockProperty Texture_Properties[]= {
+ DBP_NamedEnum("type", "type", TextureTypes),
+ DBP_Short("stype", "stype", 0.0, 0.0, 0),
+
+ DBP_Float("noisesize", "noisesize", 0.0, 0.0, 0),
+ DBP_Float("turbulence", "turbul", 0.0, 0.0, 0),
+ DBP_Float("brightness", "bright", 0.0, 0.0, 0),
+ DBP_Float("contrast", "contrast", 0.0, 0.0, 0),
+ DBP_Float("rfac", "rfac", 0.0, 0.0, 0),
+ DBP_Float("gfac", "gfac", 0.0, 0.0, 0),
+ DBP_Float("bfac", "bfac", 0.0, 0.0, 0),
+ DBP_Float("filtersize", "filtersize", 0.0, 0.0, 0),
+
+ DBP_Short("noisedepth", "noisedepth", 0.0, 0.0, 0),
+ DBP_Short("noisetype", "noisetype", 0.0, 0.0, 0),
+
+ {NULL}
+};
+*/
+
+
+/*****************************/
+/* Main interface routines */
+/*****************************/
+
+
+#define BP_CURFRAME 1
+#define BP_CURTIME 2
+#define BP_FILENAME 3
+
+static char Blender_Set_doc[]=
+"(request, data) - Update settings in Blender\n\
+\n\
+(request) A string indentifying the setting to change\n\
+ 'curframe' - Sets the current frame using the number in data";
+
+static PyObject *Blender_Set (PyObject *self, PyObject *args)
+{
+ char *name;
+ PyObject *arg;
+
+ BPY_TRY(PyArg_ParseTuple(args, "sO", &name, &arg));
+
+ if (STREQ(name, "curframe")) {
+ int framenum;
+
+ BPY_TRY(PyArg_Parse(arg, "i", &framenum));
+
+ (G.scene->r.cfra)= framenum;
+
+ update_for_newframe();
+
+ } else {
+ return BPY_err_ret_ob(PyExc_AttributeError, "bad request identifier");
+ }
+
+ return BPY_incr_ret(Py_None);
+}
+
+static char Blender_Get_doc[]=
+"(request) - Retrieve settings from Blender\n\
+\n\
+(request) A string indentifying the data to be returned\n\
+ 'curframe' - Returns the current animation frame\n\
+ 'curtime' - Returns the current animation time\n\
+ 'staframe' - Returns the start frame of the animation\n\
+ 'endframe' - Returns the end frame of the animation\n\
+ 'filename' - Returns the name of the last file read or written\n\
+ 'version' - Returns the Blender version number";
+
+static PyObject *Blender_Get (PyObject *self, PyObject *args)
+{
+ PyObject *ob;
+ PyObject *dict;
+
+ BPY_TRY(PyArg_ParseTuple(args, "O", &ob));
+
+ if (PyString_Check(ob)) {
+ char *str= PyString_AsString(ob);
+
+ if (STREQ(str, "curframe"))
+ return PyInt_FromLong((G.scene->r.cfra));
+
+ else if (STREQ(str, "curtime"))
+ return PyFloat_FromDouble(frame_to_float((G.scene->r.cfra)));
+
+ else if (STREQ(str, "staframe"))
+ return PyInt_FromLong((G.scene->r.sfra));
+
+ else if (STREQ(str, "endframe"))
+ return PyInt_FromLong((G.scene->r.efra));
+
+ else if (STREQ(str, "filename"))
+ return PyString_FromString(getGlobal()->sce);
+
+ else if (STREQ(str, "vrmloptions")) // TODO: quick hack, clean up!
+ {
+ dict= PyDict_New();
+ PyDict_SetItemString(dict, "twoside",
+ PyInt_FromLong(U.vrmlflag & USERDEF_VRML_TWOSIDED));
+ PyDict_SetItemString(dict, "layers",
+ PyInt_FromLong(U.vrmlflag & USERDEF_VRML_LAYERS));
+ PyDict_SetItemString(dict, "autoscale",
+ PyInt_FromLong(U.vrmlflag & USERDEF_VRML_AUTOSCALE));
+ return dict;
+ }
+ else if (STREQ(str, "version"))
+ return PyInt_FromLong(G.version);
+ } else {
+ return BPY_err_ret_ob(PyExc_AttributeError, "expected string argument");
+ }
+
+ return BPY_err_ret_ob(PyExc_AttributeError, "bad request identifier");
+}
+
+/* for compatibility: <<EOT */
+
+static char Blender_Redraw_doc[]= "() - Redraw all 3D windows";
+
+static PyObject *Blender_Redraw(PyObject *self, PyObject *args)
+{
+ int wintype = SPACE_VIEW3D;
+
+ BPY_TRY(PyArg_ParseTuple(args, "|i", &wintype));
+
+ return Windowmodule_Redraw(self, Py_BuildValue("(i)", wintype));
+}
+/* EOT */
+
+#undef MethodDef
+#define MethodDef(func) {#func, Blender_##func, METH_VARARGS, Blender_##func##_doc}
+
+static struct PyMethodDef Blender_methods[] = {
+ MethodDef(Redraw),
+ MethodDef(Get),
+ MethodDef(Set),
+ {NULL, NULL}
+};
+
+struct PyMethodDef Null_methods[] = {
+ {NULL, NULL}
+};
+
+
+static char Blender_Const_doc[] =
+"This module is only there for compatibility reasons.\n\
+It will disappear in future, please use the Blender.Get() syntax instead\n";
+
+
+/* Blender system module
+ Sorry, this is a mess, but had to be hacked in in order to meet deadlines..
+ TODO: Cleanup
+*/
+
+static char sys_dirname_doc[] =
+ "(path) - returns the directory name of 'path'";
+
+static PyObject *sys_dirname(PyObject *self, PyObject *args)
+{
+ PyObject *c;
+
+ char *name, dirname[256];
+ char sep;
+ int n;
+
+ BPY_TRY(PyArg_ParseTuple(args, "s", &name));
+
+ c = PyObject_GetAttrString(g_sysmodule, "dirsep");
+ sep = PyString_AsString(c)[0];
+ Py_DECREF(c);
+
+ n = strrchr(name, sep) - name;
+ if (n > 255) {
+ PyErr_SetString(PyExc_RuntimeError, "path too long");
+ return 0;
+ }
+ strncpy(dirname, name, n);
+ dirname[n] = 0;
+
+ return Py_BuildValue("s", dirname);
+}
+
+#define METHODDEF(func) {#func, sys_##func, METH_VARARGS, sys_##func##_doc}
+
+static struct PyMethodDef sys_methods[] = {
+ METHODDEF(dirname),
+ {NULL, NULL}
+};
+
+
+PyObject *init_sys(void)
+{
+
+ PyObject *m, *dict, *p;
+
+ m = Py_InitModule(SUBMODULE(sys), sys_methods);
+ g_sysmodule = m;
+
+ dict= PyModule_GetDict(m);
+
+#ifdef WIN32
+ p = Py_BuildValue("s", "\\");
+#else
+ p = Py_BuildValue("s", "/");
+#endif
+
+ PyDict_SetItemString(dict, "dirsep" , p);
+ return m;
+}
+
+/* ----------------------------------------------------------------- */
+
+void INITMODULE(BLENDERMODULE)(void)
+{
+ PyObject *m, *dict, *d;
+
+ m = Py_InitModule4(MODNAME(BLENDERMODULE), Blender_methods, (char*) 0, (PyObject*)NULL, PYTHON_API_VERSION);
+
+ DataBlock_Type.ob_type = &PyType_Type;
+
+
+ init_py_vector();
+ init_py_matrix();
+
+ dict = PyModule_GetDict(m);
+ g_blenderdict = dict;
+
+ /* pyblender data type initialization */
+ init_types(dict);
+ init_Datablockmodules(dict);
+
+ /* kept for compatibility...will be removed XXX */
+ PyDict_SetItemString(dict, "bylink", PyInt_FromLong(0));
+ PyDict_SetItemString(dict, "link", Py_None);
+
+ /* initialize submodules */
+ PyDict_SetItemString(dict, "sys", init_sys());
+ Py_INCREF(Py_None);
+ PyDict_SetItemString(dict, "Image", INITMODULE(Image)());
+ PyDict_SetItemString(dict, "Window",INITMODULE(Window)());
+ PyDict_SetItemString(dict, "NMesh", init_py_nmesh());
+ PyDict_SetItemString(dict, "Draw", init_py_draw());
+ PyDict_SetItemString(dict, "BGL", init_py_bgl());
+#ifdef EXPERIMENTAL
+ PyDict_SetItemString(dict, "Nurbs", init_py_nurbs());
+#endif
+ /* CONSTANTS */
+
+ /* emulate old python XXX -> should go to Blender/ python externals */
+
+ m = Py_InitModule4(MODNAME(BLENDERMODULE) ".Const" , Null_methods, Blender_Const_doc, (PyObject*)NULL, PYTHON_API_VERSION);
+ d = PyModule_GetDict(m);
+ PyDict_SetItemString(dict, "Const", m);
+ PyDict_SetItemString(d, "BP_CURFRAME", PyInt_FromLong(BP_CURFRAME));
+ PyDict_SetItemString(d, "BP_CURTIME", PyInt_FromLong(BP_CURTIME));
+
+ PyDict_SetItemString(d, "CURFRAME", PyInt_FromLong(BP_CURFRAME));
+ PyDict_SetItemString(d, "CURTIME", PyInt_FromLong(BP_CURTIME));
+ PyDict_SetItemString(d, "FILENAME", PyInt_FromLong(BP_FILENAME));
+}
+
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); */
+}
diff --git a/source/blender/bpython/intern/opy_datablock.h b/source/blender/bpython/intern/opy_datablock.h
new file mode 100644
index 00000000000..437b551a754
--- /dev/null
+++ b/source/blender/bpython/intern/opy_datablock.h
@@ -0,0 +1,193 @@
+/**
+ * $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 "BSE_edit.h" // for getname_< >_ei()
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BKE_scene.h"
+
+/* for a few protos: only*/
+#include "BKE_library.h"
+#include "BKE_object.h"
+#include "BKE_ika.h"
+#include "BKE_ipo.h"
+#include "BKE_key.h"
+
+#include "BLI_blenlib.h"
+#include "BLO_genfile.h" // BLO_findstruct_offset()
+#include "DNA_ID.h"
+#include "DNA_curve_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_key_types.h"
+#include "DNA_material_types.h"
+#include "DNA_object_types.h"
+#include "DNA_ipo_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_ika_types.h"
+
+#include "BPY_constobject.h"
+
+typedef struct _NamedEnum {
+ char *name;
+ int num;
+} NamedEnum;
+
+extern PyTypeObject DataBlock_Type;
+
+#define DataBlock_Check(v) ((v)->ob_type == &DataBlock_Type)
+
+typedef struct _DataBlockProperty {
+ char *public_name;
+ char *struct_name;
+
+ int type;
+#define DBP_TYPE_CHA 1 /* Char item */
+#define DBP_TYPE_SHO 2 /* Short item */
+#define DBP_TYPE_INT 3 /* Int item */
+#define DBP_TYPE_FLO 4 /* Float item */
+#define DBP_TYPE_VEC 5 /* Float vector object */
+#define DBP_TYPE_FUN 6 /* Extra2 hold function to convert ptr->ob
+ extra3 holds function to convert ob->ptr */
+
+ int stype;
+#define DBP_TYPE_NON 0
+
+ float min; /* Minimum allowed value */
+ float max; /* Maximum allowed value */
+
+ int idx[4];
+ int dlist[4];
+
+ int handling;
+#define DBP_HANDLING_NONE 0 /* No special handling required */
+#define DBP_HANDLING_FUNC 1 /* Extra1 is used to retrieve ptr */
+#define DBP_HANDLING_NENM 2 /* Extra1 holds named enum to resolve
+ values from/to. */
+
+ void *extra1;
+ void *extra2;
+ void *extra3;
+} DataBlockProperty;
+
+
+/* function pointers needed for callbacks */
+
+typedef void *(*DBGetPtrFP) (void *struct_ptr, char *name, int forsetting);
+typedef PyObject * (*DBPtrToObFP) (void **ptr);
+typedef int (*DBSetPtrFP) (void *struct_ptr, char *name, PyObject *ob);
+typedef PyObject *(*DBConvertfunc) (void *data);
+
+
+typedef struct {
+ PyObject_HEAD
+ void *data;
+ char *type;
+ ListBase *type_list;
+ DataBlockProperty *properties;
+} DataBlock;
+
+/* PROTOS */
+
+/* opy_datablock.c */
+PyObject *BPY_PyList_FromIDList(ListBase *list, DBConvertfunc convertfunc);
+PyObject *get_DataBlock_func(void **p);
+
+PyObject *py_find_from_list (ListBase *list, PyObject *args);
+PyObject *named_enum_get (int val, NamedEnum *enums);
+int named_enum_set (char *name, NamedEnum *enums);
+PyObject *datablock_getattr (DataBlockProperty *props, char *structname,
+ char *name, void *struct_ptr);
+int datablock_setattr (DataBlockProperty *props, char *structname,
+ char *name, void *struct_ptr, PyObject *setto);
+PyObject *datablock_assignIpo(DataBlock *block, DataBlock *ipoblock);
+
+
+/* DataBlock Methods */
+
+void DataBlock_dealloc (DataBlock *self);
+int DataBlock_print (PyObject *self, FILE *fp, int flags);
+PyObject *DataBlock_getattr (PyObject *self, char *name);
+int DataBlock_setattr (PyObject *self, char *name, PyObject *ob);
+int DataBlock_type(DataBlock *block);
+int DataBlock_isType (DataBlock *block, int type);
+PyObject *DataBlock_fromData (void *data);
+PyObject *DataBlock_link(PyObject *self, PyObject *args);
+
+PyObject *make_icu_list (ListBase *curves);
+void pybzt_dealloc (PyObject *self);
+int pybzt_print (PyObject *self, FILE *fp, int flags);
+PyObject *pybzt_getattr (PyObject *self, char *name);
+int pybzt_setattr (PyObject *self, char *name, PyObject *ob);
+PyObject *pybzt_create (PyObject *self, PyObject *args);
+PyObject *pybzt_from_bzt (BezTriple *bzt);
+void pyicu_dealloc (PyObject *self);
+int pyicu_print (PyObject *self, FILE *fp, int flags);
+PyObject *pyicu_getattr (PyObject *self, char *name);
+int pyicu_setattr (PyObject *self, char *name, PyObject *ob);
+PyObject *pyicu_from_icu (IpoCurve *icu);
+PyObject *Ipo_Recalc (PyObject *self, PyObject *args);
+PyObject *Ipo_Eval (PyObject *self, PyObject *args);
+void init_types (PyObject *dict);
+void init_Datablockmodules (PyObject *dict);
+PyObject *getInverseMatrix(void *vdata);
+
+
+/* Object module */
+void *Object_special_getattr(void *vdata, char *name);
+int Object_special_setattr(void *vdata, char *name, PyObject *py_ob);
+
+extern PyObject *initObject(void);
+extern struct PyMethodDef Objectmodule_methods[];
+extern struct PyMethodDef Object_methods[];
+extern DataBlockProperty Object_Properties[];
+
+extern struct PyMethodDef Imagemodule_methods[];
+extern DataBlockProperty Image_Properties[];
+extern PyObject *initScene(void);
+extern struct PyMethodDef Scenemodule_methods[];
+
+extern PyObject *initIpo(void);
+extern struct PyMethodDef Ipo_methods[];
+extern struct PyMethodDef Ipomodule_methods[];
+extern DataBlockProperty Ipo_Properties[];
+
+
+extern struct PyMethodDef Textmodule_methods[];
+extern struct PyMethodDef Text_methods[];
+extern DataBlockProperty Text_Properties[];
+
+
+
+struct Material;
+
+struct
+Material **newMaterialList_fromPyList(PyObject *list);
+PyObject *PyList_fromMaterialList(struct Material **matlist, int len);
diff --git a/source/blender/bpython/intern/opy_draw.c b/source/blender/bpython/intern/opy_draw.c
new file mode 100644
index 00000000000..23929b1392f
--- /dev/null
+++ b/source/blender/bpython/intern/opy_draw.c
@@ -0,0 +1,2679 @@
+/* python.c MIXED MODEL
+ *
+ * june 99
+ * $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 *****
+ */
+
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "MEM_guardedalloc.h"
+
+#include "BMF_Api.h"
+
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_text_types.h"
+
+#include "BKE_global.h"
+
+#include "BIF_gl.h"
+#include "BIF_screen.h"
+#include "BIF_space.h"
+#include "BIF_interface.h"
+#include "BIF_mywindow.h"
+
+#include "interface.h"
+#include "mydevice.h" /* for all the event constants */
+
+#include "Python.h"
+#include "BPY_macros.h"
+#include "BPY_main.h"
+#include "BPY_tools.h"
+
+int disable_force_draw= 0;
+
+/* hack to flag that window redraw has happened inside slider callback: */
+
+static void exit_pydraw (SpaceText *st);
+static uiBlock *Get_uiBlock (void);
+void initDraw (void);
+
+/* Button Object */
+
+typedef struct _Button {
+ PyObject_VAR_HEAD
+
+ int type; /* 1 == int, 2 == float, 3 == string */
+ int slen; /* length of string (if type == 3) */
+ union {
+ int asint;
+ float asfloat;
+ char *asstr;
+ } val;
+} Button;
+
+
+static void Button_dealloc(PyObject *self) {
+ Button *but= (Button*) self;
+
+ if(but->type==3) MEM_freeN(but->val.asstr);
+
+ PyMem_DEL(self);
+}
+
+static PyObject *Button_getattr(PyObject *self, char *name) {
+ Button *but= (Button*) self;
+
+ if(STREQ(name, "val")) {
+ if (but->type==1)
+ return Py_BuildValue("i", but->val.asint);
+ else if (but->type==2)
+ return Py_BuildValue("f", but->val.asfloat);
+ else if (but->type==3)
+ return Py_BuildValue("s", but->val.asstr);
+ }
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+}
+
+static int Button_setattr(PyObject *self, char *name, PyObject *v) {
+ Button *but= (Button*) self;
+
+ if(STREQ(name, "val")) {
+ if (but->type==1)
+ PyArg_Parse(v, "i", &but->val.asint);
+ else if (but->type==2)
+ PyArg_Parse(v, "f", &but->val.asfloat);
+ else if (but->type==3) {
+ char *newstr;
+
+ PyArg_Parse(v, "s", &newstr);
+ strncpy(but->val.asstr, newstr, but->slen);
+ }
+ } else {
+ PyErr_SetString(PyExc_AttributeError, name);
+ return -1;
+ }
+
+ return 0;
+}
+
+static PyObject *Button_repr(PyObject *self) {
+ return PyObject_Repr(Button_getattr(self, "val"));
+}
+
+PyTypeObject Button_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "Button", /*tp_name*/
+ sizeof(Button), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ (destructor) Button_dealloc, /*tp_dealloc*/
+ (printfunc) 0, /*tp_print*/
+ (getattrfunc) Button_getattr, /*tp_getattr*/
+ (setattrfunc) Button_setattr, /*tp_setattr*/
+ (cmpfunc) 0, /*tp_cmp*/
+ (reprfunc) Button_repr, /*tp_repr*/
+};
+
+
+static Button *newbutton (void) {
+ Button *but= (Button *) PyObject_NEW(Button, &Button_Type);
+
+ return but;
+}
+
+
+/* GUI interface routines */
+
+static void exit_pydraw(SpaceText *st)
+{
+ scrarea_queue_redraw(st->area);
+
+ if (st) {
+ Py_XDECREF((PyObject *) st->py_draw);
+ Py_XDECREF((PyObject *) st->py_event);
+ Py_XDECREF((PyObject *) st->py_button);
+
+ st->py_draw= st->py_event= st->py_button= NULL;
+ }
+}
+
+static void exec_callback(SpaceText *st, PyObject *callback, PyObject *args)
+{
+ PyObject *result= PyEval_CallObject(callback, args);
+
+ if (result==NULL) {
+ st->text->compiled= NULL;
+ PyErr_Print();
+ exit_pydraw(st);
+ }
+ Py_XDECREF(result);
+ Py_DECREF(args);
+}
+
+/* the handler for drawing routines (see Register method) */
+
+void BPY_spacetext_do_pywin_draw(SpaceText *st)
+{
+ uiBlock *block;
+ char butblock[20];
+
+ sprintf(butblock, "win %d", curarea->win);
+ block= uiNewBlock(&curarea->uiblocks, butblock, UI_EMBOSSX, UI_HELV, curarea->win);
+
+ if (st->py_draw) {
+ glPushAttrib(GL_ALL_ATTRIB_BITS);
+ exec_callback(st, st->py_draw, Py_BuildValue("()"));
+ glPopAttrib();
+ } else {
+ glClearColor(0.4375, 0.4375, 0.4375, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+
+ uiDrawBlock(block);
+
+ curarea->win_swap= WIN_BACK_OK;
+}
+
+/* the handler for button event routines (see Register method) */
+
+static void spacetext_do_pywin_buttons(SpaceText *st, unsigned short event) {
+ if (st->py_button) {
+ exec_callback(st, st->py_button, Py_BuildValue("(i)", event));
+ }
+}
+
+/* calls the generic event handling methods registered with Register */
+
+void BPY_spacetext_do_pywin_event(SpaceText *st, unsigned short event, short val) {
+ if (event==QKEY && G.qual & (LR_ALTKEY|LR_CTRLKEY|LR_SHIFTKEY)) {
+ exit_pydraw(st);
+ return;
+ }
+
+ if (val) {
+ if (uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
+
+ if (event==UI_BUT_EVENT) {
+ spacetext_do_pywin_buttons(st, val);
+ }
+ }
+
+ if (st->py_event) {
+ exec_callback(st, st->py_event, Py_BuildValue("(ii)", event, val));
+ }
+}
+
+int BPY_spacetext_is_pywin(SpaceText *st) {
+ return (st->py_draw || st->py_event || st->py_button);
+}
+
+static char Method_Exit_doc[]=
+"() - Exit the windowing interface";
+static PyObject *Method_Exit (PyObject *self, PyObject *args)
+{
+ SpaceText *st= curarea->spacedata.first;
+#ifdef CLEAR_NAMESPACE
+ PyObject *d;
+#endif
+ BPY_TRY(PyArg_ParseTuple(args, ""));
+
+ exit_pydraw(st);
+#ifdef CLEAR_NAMESPACE
+ d = st->py_globaldict; // The current window's global namespace dictionary
+ if (d) {
+ PyDict_Clear(d);
+ Py_DECREF(d); // release dictionary
+ }
+#endif
+
+ return BPY_incr_ret(Py_None);
+}
+
+static char Method_Register_doc[]=
+"(draw, event, button) - Register callbacks for windowing\n\
+\n\
+(draw) A function to draw the screen, taking no arguments\n\
+(event) A function to handle events, taking 2 arguments (evt, val)\n\
+ (evt) The event number\n\
+ (val) The value modifier (for key and mouse press/release)\n\
+(button) A function to handle button events, taking 1 argument (evt)\n\
+ (evt) The button number\n\
+\n\
+A None object can be passed if a callback is unused.";
+
+static PyObject *Method_Register (PyObject *self, PyObject *args)
+{
+ PyObject *newdrawc= NULL, *neweventc= NULL, *newbuttonc= NULL;
+ SpaceText *st= curarea->spacedata.first;
+
+ BPY_TRY(PyArg_ParseTuple(args, "O|OO", &newdrawc, &neweventc, &newbuttonc));
+
+ /* This is a hack again:
+ * Every python script should actually do a global variable cleanup at
+ * the end of execution.
+ * For scripts registering GUI callbacks, this does not work, because
+ * the global namespace of the interpreter still needs to be accessed
+ * from the callback.
+ * Workaround: a text object has a flag which allows the global name
+ * space to be cleared at the end of the script. This flag should be
+ * normally set when executed with Alt-P. For a script registering with
+ * the GUI though, clear the flag and set it when the GUI mode is left
+ * (Method_Exit).
+ */
+
+ BPY_debug(("--- disable clear namespace"));
+
+ st->flags &= ~ST_CLEAR_NAMESPACE;
+
+
+ if (!PyCallable_Check(newdrawc)) newdrawc= NULL;
+ if (!PyCallable_Check(neweventc)) neweventc= NULL;
+ if (!PyCallable_Check(newbuttonc)) newbuttonc= NULL;
+
+ if (!(newdrawc || neweventc || newbuttonc))
+ return BPY_incr_ret(Py_None);
+
+ exit_pydraw(st);
+
+ Py_XINCREF(newdrawc);
+ Py_XINCREF(neweventc);
+ Py_XINCREF(newbuttonc);
+
+ st->py_draw= newdrawc;
+ st->py_event= neweventc;
+ st->py_button= newbuttonc;
+
+ scrarea_queue_redraw(st->area);
+
+ return BPY_incr_ret(Py_None);
+}
+
+
+static char Method_Redraw_doc[]=
+"([after]) - Queue a redraw event\n\
+\n\
+[after=0] Determines whether the redraw is processed before or after other input events.\n\
+\n\
+Redraw events are buffered so that regardless of how many events are queued\n\
+the window only receives one redraw event.";
+
+static PyObject *Method_Redraw (PyObject *self, PyObject *args)
+{
+ int after= 0;
+
+ BPY_TRY(PyArg_ParseTuple(args, "|i", &after));
+
+ if (after) addafterqueue(curarea->win, REDRAW, 1);
+ else scrarea_queue_winredraw(curarea);
+
+ return BPY_incr_ret(Py_None);
+}
+
+
+static char Method_Draw_doc[]=
+"() - Force an immediate redraw\n\
+\n\
+Forced redraws are not buffered, in other words the window is redrawn\n\
+exactly once for everytime this function is called.";
+static PyObject *Method_Draw (PyObject *self, PyObject *args)
+{
+ /* If forced drawing is disable queue a redraw event instead */
+ if (disable_force_draw) {
+ scrarea_queue_winredraw(curarea);
+ return BPY_incr_ret(Py_None);
+ }
+
+ BPY_TRY(PyArg_ParseTuple(args, ""));
+
+ scrarea_do_windraw(curarea);
+
+ screen_swapbuffers();
+
+ return BPY_incr_ret(Py_None);
+}
+
+
+
+static char Method_Create_doc[]=
+"(value) - Create a default Button object\n\
+\n\
+(value) - The value to store in the button\n\
+\n\
+Valid values are ints, floats, and strings";
+
+static PyObject *Method_Create (PyObject *self, PyObject *args)
+{
+ Button *but;
+ PyObject *in;
+
+ BPY_TRY(PyArg_ParseTuple(args, "O", &in));
+
+ but= newbutton();
+ if(PyFloat_Check(in)) {
+ but->type= 2;
+ but->val.asfloat= PyFloat_AsDouble(in);
+ } else if (PyInt_Check(in)) {
+ but->type= 1;
+ but->val.asint= PyInt_AsLong(in);
+ } else if (PyString_Check(in)) {
+ char *newstr= PyString_AsString(in);
+
+ but->type= 3;
+ but->slen= strlen(newstr);
+ but->val.asstr= MEM_mallocN(but->slen+1, "button string");
+
+ strcpy(but->val.asstr, newstr);
+ }
+
+ return (PyObject *) but;
+}
+
+static uiBlock *Get_uiBlock(void)
+{
+ char butblock[32];
+
+ sprintf(butblock, "win %d", curarea->win);
+
+ return uiGetBlock(butblock, curarea);
+}
+
+static char Method_Button_doc[]=
+"(name, event, x, y, width, height, [tooltip]) - Create a new Button (push) button\n\
+\n\
+(name) A string to display on the button\n\
+(event) The event number to pass to the button event function when activated\n\
+(x, y) The lower left coordinate of the button\n\
+(width, height) The button width and height\n\
+[tooltip=""] The button's tooltip";
+
+static PyObject *Method_Button (PyObject *self, PyObject *args)
+{
+ uiBlock *block;
+ char *name, *tip= NULL;
+ int event;
+ int x, y, w, h;
+
+ BPY_TRY(PyArg_ParseTuple(args, "siiiii|s", &name, &event, &x, &y, &w, &h, &tip));
+
+ block= Get_uiBlock();
+
+ if(block) uiDefBut(block, BUT, event, name, x, y, w, h, 0, 0, 0, 0, 0, tip);
+
+ return BPY_incr_ret(Py_None);
+}
+
+static char Method_Menu_doc[]=
+"(name, event, x, y, width, height, default, [tooltip]) - Create a new Menu button\n\
+\n\
+(name) A string to display on the button\n\
+(event) The event number to pass to the button event function when activated\n\
+(x, y) The lower left coordinate of the button\n\
+(width, height) The button width and height\n\
+(default) The number of the option to be selected by default\n\
+[tooltip=""] The button's tooltip\n\
+\n\
+The menu options are specified through the name of the\n\
+button. Options are followed by a format code and seperated\n\
+by the '|' (pipe) character.\n\
+Valid format codes are\n\
+ %t - The option should be used as the title\n\
+ %xN - The option should set the integer N in the button value.";
+
+static PyObject *Method_Menu (PyObject *self, PyObject *args)
+{
+ uiBlock *block;
+ char *name, *tip= NULL;
+ int event, def;
+ int x, y, w, h;
+ Button *but;
+
+ BPY_TRY(PyArg_ParseTuple(args, "siiiiii|s", &name, &event, &x, &y, &w, &h, &def, &tip));
+
+ but= newbutton();
+ but->type= 1;
+ but->val.asint= def;
+
+ block= Get_uiBlock();
+ if(block) uiDefButI(block, MENU, event, name, x, y, w, h, &but->val.asint, 0, 0, 0, 0, tip);
+
+ return (PyObject *) but;
+}
+
+static char Method_Toggle_doc[]=
+"(name, event, x, y, width, height, default, [tooltip]) - Create a new Toggle button\n\
+\n\
+(name) A string to display on the button\n\
+(event) The event number to pass to the button event function when activated\n\
+(x, y) The lower left coordinate of the button\n\
+(width, height) The button width and height\n\
+(default) An integer (0 or 1) specifying the default state\n\
+[tooltip=""] The button's tooltip";
+
+static PyObject *Method_Toggle (PyObject *self, PyObject *args)
+{
+ uiBlock *block;
+ char *name, *tip= NULL;
+ int event;
+ int x, y, w, h, def;
+ Button *but;
+
+ BPY_TRY(PyArg_ParseTuple(args, "siiiiii|s", &name, &event, &x, &y, &w, &h, &def, &tip));
+
+ but= newbutton();
+ but->type= 1;
+ but->val.asint= def;
+
+ block= Get_uiBlock();
+ if(block) uiDefButI(block, TOG, event, name, x, y, w, h, &but->val.asint, 0, 0, 0, 0, tip);
+
+ return (PyObject *) but;
+}
+
+
+/* DO NOT TOUCH THIS FUNCTION !
+ Redrawing a slider inside its own callback routine is actually forbidden
+ with the current toolkit architecture (button routines are not reentrant).
+ But it works anyway.
+ XXX This is condemned to be dinosource in future - it's a hack.
+ */
+
+static void py_slider_update(void *butv, void *data2_unused)
+{
+ uiBut *but= butv;
+
+ disable_force_draw= 1;
+ /*
+ Disable forced drawing, otherwise the button object which
+ is still being used might be deleted
+ */
+
+// UIfrontbuf = 0;
+// spacetext_do_pywin_buttons(curarea->spacedata.first, but->retval);
+
+ g_window_redrawn = 0;
+ curarea->win_swap= WIN_BACK_OK;
+ UIfrontbuf = 1;
+ spacetext_do_pywin_buttons(curarea->spacedata.first, uiButGetRetVal(but));
+ UIfrontbuf = 0;
+
+ if (!g_window_redrawn) /* if Redraw already called */
+ Windowmodule_Redraw(0, Py_BuildValue("(i)", SPACE_VIEW3D));
+
+ disable_force_draw= 0;
+}
+
+static char Method_Slider_doc[]=
+"(name, event, x, y, width, height, initial, min, max, [update, tooltip]) - Create a new Slider button\n\
+\n\
+(name) A string to display on the button\n\
+(event) The event number to pass to the button event function when activated\n\
+(x, y) The lower left coordinate of the button\n\
+(width, height) The button width and height\n\
+(initial, min, max) Three values (int or float) specifying the initial and limit values.\n\
+[update=1] A value controlling whether the slider will emit events as it is edited.\n\
+ A non-zero value (default) enables the events. A zero value supresses them.\n\
+[tooltip=""] The button's tooltip";
+
+static PyObject *Method_Slider (PyObject *self, PyObject *args)
+{
+ uiBlock *block;
+ char *name, *tip= NULL;
+ int event;
+ int x, y, w, h, realtime=1;
+ Button *but;
+ PyObject *mino, *maxo, *inio;
+
+ BPY_TRY(PyArg_ParseTuple(args, "siiiiiOOO|is", &name, &event, &x, &y, &w, &h, &inio, &mino, &maxo, &realtime, &tip));
+
+
+ but= newbutton();
+ if (PyFloat_Check(inio)) {
+ float ini, min, max;
+
+ ini= PyFloat_AsDouble(inio);
+ min= PyFloat_AsDouble(mino);
+ max= PyFloat_AsDouble(maxo);
+
+ but->type= 2;
+ but->val.asfloat= ini;
+
+ block= Get_uiBlock();
+ if(block) {
+ uiBut *ubut;
+ ubut= uiDefButF(block, NUMSLI, event, name, x, y, w, h, &but->val.asfloat, min, max, 0, 0, tip);
+ if (realtime) uiButSetFunc(ubut, py_slider_update, ubut, NULL);
+ }
+ }
+ else {
+ int ini, min, max;
+
+ ini= PyInt_AsLong(inio);
+ min= PyInt_AsLong(mino);
+ max= PyInt_AsLong(maxo);
+
+ but->type= 1;
+ but->val.asint= ini;
+
+ block= Get_uiBlock();
+ if(block) {
+ uiBut *ubut;
+ ubut= uiDefButI(block, NUMSLI, event, name, x, y, w, h, &but->val.asint, min, max, 0, 0, tip);
+ if (realtime) uiButSetFunc(ubut, py_slider_update, ubut, NULL);
+ }
+ }
+ return (PyObject *) but;
+}
+
+static char Method_Scrollbar_doc[]=
+"(event, x, y, width, height, initial, min, max, [update, tooltip]) - Create a new Scrollbar\n\
+\n\
+(event) The event number to pass to the button event function when activated\n\
+(x, y) The lower left coordinate of the button\n\
+(width, height) The button width and height\n\
+(initial, min, max) Three values (int or float) specifying the initial and limit values.\n\
+[update=1] A value controlling whether the slider will emit events as it is edited.\n\
+ A non-zero value (default) enables the events. A zero value supresses them.\n\
+[tooltip=""] The button's tooltip";
+
+static PyObject *Method_Scrollbar (PyObject *self, PyObject *args)
+{
+ char *tip= NULL;
+ uiBlock *block;
+ int event;
+ int x, y, w, h, realtime=1;
+ Button *but;
+ PyObject *mino, *maxo, *inio;
+ float ini, min, max;
+
+ BPY_TRY(PyArg_ParseTuple(args, "iiiiiOOO|is", &event, &x, &y, &w, &h, &inio, &mino, &maxo, &realtime, &tip));
+
+ if (!PyNumber_Check(inio) || !PyNumber_Check(inio) || !PyNumber_Check(inio))
+ return BPY_err_ret_ob(PyExc_AttributeError, "expected numbers for initial, min, and max");
+
+ but= newbutton();
+
+ if (PyFloat_Check(inio)) but->type= 2;
+ else but->type= 1;
+
+ ini= PyFloat_AsDouble(inio);
+ min= PyFloat_AsDouble(mino);
+ max= PyFloat_AsDouble(maxo);
+
+ if (but->type==2) {
+ but->val.asfloat= ini;
+ block= Get_uiBlock();
+ if(block) {
+ uiBut *ubut;
+ ubut= uiDefButF(block, SCROLL, event, "", x, y, w, h, &but->val.asfloat, min, max, 0, 0, tip);
+ if (realtime) uiButSetFunc(ubut, py_slider_update, ubut, NULL);
+ }
+ } else {
+ but->val.asint= ini;
+ block= Get_uiBlock();
+ if(block) {
+ uiBut *ubut;
+ ubut= uiDefButI(block, SCROLL, event, "", x, y, w, h, &but->val.asint, min, max, 0, 0, tip);
+ if (realtime) uiButSetFunc(ubut, py_slider_update, ubut, NULL);
+ }
+ }
+
+ return (PyObject *) but;
+}
+
+static char Method_Number_doc[]=
+"(name, event, x, y, width, height, initial, min, max, [tooltip]) - Create a new Number button\n\
+\n\
+(name) A string to display on the button\n\
+(event) The event number to pass to the button event function when activated\n\
+(x, y) The lower left coordinate of the button\n\
+(width, height) The button width and height\n\
+(initial, min, max) Three values (int or float) specifying the initial and limit values.\n\
+[tooltip=""] The button's tooltip";
+
+static PyObject *Method_Number (PyObject *self, PyObject *args)
+{
+ uiBlock *block;
+ char *name, *tip= NULL;
+ int event;
+ int x, y, w, h;
+ Button *but;
+ PyObject *mino, *maxo, *inio;
+
+ BPY_TRY(PyArg_ParseTuple(args, "siiiiiOOO|s", &name, &event, &x, &y, &w, &h, &inio, &mino, &maxo, &tip));
+
+ but= newbutton();
+
+ if (PyFloat_Check(inio)) {
+ float ini, min, max;
+
+ ini= PyFloat_AsDouble(inio);
+ min= PyFloat_AsDouble(mino);
+ max= PyFloat_AsDouble(maxo);
+
+ but->type= 2;
+ but->val.asfloat= ini;
+
+ block= Get_uiBlock();
+ if(block) uiDefButF(block, NUM, event, name, x, y, w, h, &but->val.asfloat, min, max, 0, 0, tip);
+ } else {
+ int ini, min, max;
+
+ ini= PyInt_AsLong(inio);
+ min= PyInt_AsLong(mino);
+ max= PyInt_AsLong(maxo);
+
+ but->type= 1;
+ but->val.asint= ini;
+
+ block= Get_uiBlock();
+ if(block) uiDefButI(block, NUM, event, name, x, y, w, h, &but->val.asint, min, max, 0, 0, tip);
+ }
+
+ return (PyObject *) but;
+}
+
+static char Method_String_doc[]=
+"(name, event, x, y, width, height, initial, length, [tooltip]) - Create a new String button\n\
+\n\
+(name) A string to display on the button\n\
+(event) The event number to pass to the button event function when activated\n\
+(x, y) The lower left coordinate of the button\n\
+(width, height) The button width and height\n\
+(initial) The string to display initially\n\
+(length) The maximum input length\n\
+[tooltip=""] The button's tooltip";
+
+static PyObject *Method_String (PyObject *self, PyObject *args)
+{
+ uiBlock *block;
+ char *name, *tip= NULL, *newstr;
+ int event;
+ int x, y, w, h, len;
+ Button *but;
+
+ BPY_TRY(PyArg_ParseTuple(args, "siiiiisi|s", &name, &event, &x, &y, &w, &h, &newstr, &len, &tip));
+
+ but= newbutton();
+ but->type= 3;
+ but->slen= len;
+ but->val.asstr= MEM_mallocN(len+1, "button string");
+
+ strncpy(but->val.asstr, newstr, len);
+ but->val.asstr[len]= 0;
+
+ block= Get_uiBlock();
+ if(block) uiDefBut(block, TEX, event, name, x, y, w, h, but->val.asstr, 0, len, 0, 0, tip);
+
+ return (PyObject *) but;
+}
+
+static char Method_Text_doc[]=
+"(text) - Draw text onscreen\n\
+\n\
+(text) The text to draw\n";
+static PyObject *Method_Text (PyObject *self, PyObject *args)
+{
+ char *text;
+
+ BPY_TRY(PyArg_ParseTuple(args, "s", &text));
+
+ BMF_DrawString(G.font, text);
+
+ return BPY_incr_ret(Py_None);
+}
+
+#undef MethodDef
+#define MethodDef(func) _MethodDef(func, Method)
+
+static struct PyMethodDef Draw_methods[] = {
+ MethodDef(Create),
+ MethodDef(Button),
+ MethodDef(Toggle),
+ MethodDef(Menu),
+ MethodDef(Slider),
+ MethodDef(Scrollbar),
+ MethodDef(Number),
+ MethodDef(String),
+
+ MethodDef(Text),
+
+ MethodDef(Exit),
+ MethodDef(Redraw),
+ MethodDef(Draw),
+ MethodDef(Register),
+
+ {NULL, NULL}
+};
+
+PyObject *init_py_draw(void)
+{
+ PyObject *mod= Py_InitModule(SUBMODULE(Draw), Draw_methods);
+ PyObject *dict= PyModule_GetDict(mod);
+
+ Button_Type.ob_type= &PyType_Type;
+
+ BPY_ADDCONST(dict, LEFTMOUSE);
+ BPY_ADDCONST(dict, MIDDLEMOUSE);
+ BPY_ADDCONST(dict, RIGHTMOUSE);
+ BPY_ADDCONST(dict, MOUSEX);
+ BPY_ADDCONST(dict, MOUSEY);
+ BPY_ADDCONST(dict, TIMER0);
+ BPY_ADDCONST(dict, TIMER1);
+ BPY_ADDCONST(dict, TIMER2);
+ BPY_ADDCONST(dict, TIMER3);
+ BPY_ADDCONST(dict, KEYBD);
+ BPY_ADDCONST(dict, RAWKEYBD);
+ BPY_ADDCONST(dict, REDRAW);
+ BPY_ADDCONST(dict, INPUTCHANGE);
+ BPY_ADDCONST(dict, QFULL);
+ BPY_ADDCONST(dict, WINFREEZE);
+ BPY_ADDCONST(dict, WINTHAW);
+ BPY_ADDCONST(dict, WINCLOSE);
+ BPY_ADDCONST(dict, WINQUIT);
+#ifndef IRISGL
+ BPY_ADDCONST(dict, Q_FIRSTTIME);
+#endif
+ BPY_ADDCONST(dict, AKEY);
+ BPY_ADDCONST(dict, BKEY);
+ BPY_ADDCONST(dict, CKEY);
+ BPY_ADDCONST(dict, DKEY);
+ BPY_ADDCONST(dict, EKEY);
+ BPY_ADDCONST(dict, FKEY);
+ BPY_ADDCONST(dict, GKEY);
+ BPY_ADDCONST(dict, HKEY);
+ BPY_ADDCONST(dict, IKEY);
+ BPY_ADDCONST(dict, JKEY);
+ BPY_ADDCONST(dict, KKEY);
+ BPY_ADDCONST(dict, LKEY);
+ BPY_ADDCONST(dict, MKEY);
+ BPY_ADDCONST(dict, NKEY);
+ BPY_ADDCONST(dict, OKEY);
+ BPY_ADDCONST(dict, PKEY);
+ BPY_ADDCONST(dict, QKEY);
+ BPY_ADDCONST(dict, RKEY);
+ BPY_ADDCONST(dict, SKEY);
+ BPY_ADDCONST(dict, TKEY);
+ BPY_ADDCONST(dict, UKEY);
+ BPY_ADDCONST(dict, VKEY);
+ BPY_ADDCONST(dict, WKEY);
+ BPY_ADDCONST(dict, XKEY);
+ BPY_ADDCONST(dict, YKEY);
+ BPY_ADDCONST(dict, ZKEY);
+ BPY_ADDCONST(dict, ZEROKEY);
+ BPY_ADDCONST(dict, ONEKEY);
+ BPY_ADDCONST(dict, TWOKEY);
+ BPY_ADDCONST(dict, THREEKEY);
+ BPY_ADDCONST(dict, FOURKEY);
+ BPY_ADDCONST(dict, FIVEKEY);
+ BPY_ADDCONST(dict, SIXKEY);
+ BPY_ADDCONST(dict, SEVENKEY);
+ BPY_ADDCONST(dict, EIGHTKEY);
+ BPY_ADDCONST(dict, NINEKEY);
+ BPY_ADDCONST(dict, CAPSLOCKKEY);
+ BPY_ADDCONST(dict, LEFTCTRLKEY);
+ BPY_ADDCONST(dict, LEFTALTKEY);
+ BPY_ADDCONST(dict, RIGHTALTKEY);
+ BPY_ADDCONST(dict, RIGHTCTRLKEY);
+ BPY_ADDCONST(dict, RIGHTSHIFTKEY);
+ BPY_ADDCONST(dict, LEFTSHIFTKEY);
+ BPY_ADDCONST(dict, ESCKEY);
+ BPY_ADDCONST(dict, TABKEY);
+ BPY_ADDCONST(dict, RETKEY);
+ BPY_ADDCONST(dict, SPACEKEY);
+ BPY_ADDCONST(dict, LINEFEEDKEY);
+ BPY_ADDCONST(dict, BACKSPACEKEY);
+ BPY_ADDCONST(dict, DELKEY);
+ BPY_ADDCONST(dict, SEMICOLONKEY);
+ BPY_ADDCONST(dict, PERIODKEY);
+ BPY_ADDCONST(dict, COMMAKEY);
+ BPY_ADDCONST(dict, QUOTEKEY);
+ BPY_ADDCONST(dict, ACCENTGRAVEKEY);
+ BPY_ADDCONST(dict, MINUSKEY);
+ BPY_ADDCONST(dict, SLASHKEY);
+ BPY_ADDCONST(dict, BACKSLASHKEY);
+ BPY_ADDCONST(dict, EQUALKEY);
+ BPY_ADDCONST(dict, LEFTBRACKETKEY);
+ BPY_ADDCONST(dict, RIGHTBRACKETKEY);
+ BPY_ADDCONST(dict, LEFTARROWKEY);
+ BPY_ADDCONST(dict, DOWNARROWKEY);
+ BPY_ADDCONST(dict, RIGHTARROWKEY);
+ BPY_ADDCONST(dict, UPARROWKEY);
+ BPY_ADDCONST(dict, PAD2);
+ BPY_ADDCONST(dict, PAD4);
+ BPY_ADDCONST(dict, PAD6);
+ BPY_ADDCONST(dict, PAD8);
+ BPY_ADDCONST(dict, PAD1);
+ BPY_ADDCONST(dict, PAD3);
+ BPY_ADDCONST(dict, PAD5);
+ BPY_ADDCONST(dict, PAD7);
+ BPY_ADDCONST(dict, PAD9);
+ BPY_ADDCONST(dict, PADPERIOD);
+ BPY_ADDCONST(dict, PADSLASHKEY);
+ BPY_ADDCONST(dict, PADASTERKEY);
+ BPY_ADDCONST(dict, PAD0);
+ BPY_ADDCONST(dict, PADMINUS);
+ BPY_ADDCONST(dict, PADENTER);
+ BPY_ADDCONST(dict, PADPLUSKEY);
+ BPY_ADDCONST(dict, F1KEY);
+ BPY_ADDCONST(dict, F2KEY);
+ BPY_ADDCONST(dict, F3KEY);
+ BPY_ADDCONST(dict, F4KEY);
+ BPY_ADDCONST(dict, F5KEY);
+ BPY_ADDCONST(dict, F6KEY);
+ BPY_ADDCONST(dict, F7KEY);
+ BPY_ADDCONST(dict, F8KEY);
+ BPY_ADDCONST(dict, F9KEY);
+ BPY_ADDCONST(dict, F10KEY);
+ BPY_ADDCONST(dict, F11KEY);
+ BPY_ADDCONST(dict, F12KEY);
+ BPY_ADDCONST(dict, PAUSEKEY);
+ BPY_ADDCONST(dict, INSERTKEY);
+ BPY_ADDCONST(dict, HOMEKEY);
+ BPY_ADDCONST(dict, PAGEUPKEY);
+ BPY_ADDCONST(dict, PAGEDOWNKEY);
+ BPY_ADDCONST(dict, ENDKEY);
+
+ return mod;
+}
+
+
+/* Buffer Object */
+
+/* For Python access to OpenGL functions requiring
+ * a pointer.
+ */
+
+PyTypeObject Buffer_Type;
+
+typedef struct _Buffer {
+ PyObject_VAR_HEAD
+
+ PyObject *parent;
+
+ int type; /* GL_BYTE, GL_SHORT, GL_INT, GL_FLOAT */
+ int ndimensions;
+ int *dimensions;
+
+ union {
+ char *asbyte;
+ short *asshort;
+ int *asint;
+ float *asfloat;
+
+ void *asvoid;
+ } buf;
+} Buffer;
+
+static int type_size(int type) {
+ switch (type) {
+ case GL_BYTE:
+ return sizeof(char);
+ case GL_SHORT:
+ return sizeof(short);
+ case GL_INT:
+ return sizeof(int);
+ case GL_FLOAT:
+ return sizeof(float);
+ }
+ return -1;
+}
+
+static Buffer *make_buffer(int type, int ndimensions, int *dimensions) {
+ Buffer *buffer;
+ void *buf= NULL;
+ int i, size, length;
+
+ length= 1;
+ for (i=0; i<ndimensions; i++) length*= dimensions[i];
+
+ size= type_size(type);
+
+ buf= MEM_mallocN(length*size, "Buffer buffer");
+
+ buffer= (Buffer *) PyObject_NEW(Buffer, &Buffer_Type);
+ buffer->parent= NULL;
+ buffer->ndimensions= ndimensions;
+ buffer->dimensions= dimensions;
+ buffer->type= type;
+ buffer->buf.asvoid= buf;
+
+ for (i= 0; i<length; i++) {
+ if (type==GL_BYTE)
+ buffer->buf.asbyte[i]= 0;
+
+ else if (type==GL_SHORT)
+ buffer->buf.asshort[i]= 0;
+
+ else if (type==GL_INT)
+ buffer->buf.asint[i]= 0;
+
+ else if (type==GL_FLOAT)
+ buffer->buf.asfloat[i]= 0.0;
+ }
+
+ return buffer;
+}
+
+static int Buffer_ass_slice(PyObject *self, int begin, int end, PyObject *seq);
+
+static char Method_Buffer_doc[]=
+"(type, dimensions, [template]) - Create a new Buffer object\n\
+\n\
+(type) - The format to store data in\n\
+(dimensions) - An int or sequence specifying the dimensions of the buffer\n\
+[template] - A sequence of matching dimensions to the buffer to be created\n\
+ which will be used to initialize the Buffer.\n\
+\n\
+If a template is not passed in all fields will be initialized to 0.\n\
+\n\
+The type should be one of GL_BYTE, GL_SHORT, GL_INT, or GL_FLOAT.\n\
+If the dimensions are specified as an int a linear buffer will be\n\
+created. If a sequence is passed for the dimensions the buffer\n\
+will have len(sequence) dimensions, where the size for each dimension\n\
+is determined by the value in the sequence at that index.\n\
+\n\
+For example, passing [100, 100] will create a 2 dimensional\n\
+square buffer. Passing [16, 16, 32] will create a 3 dimensional\n\
+buffer which is twice as deep as it is wide or high.";
+
+static PyObject *Method_Buffer (PyObject *self, PyObject *args)
+{
+ PyObject *length_ob= NULL, *template= NULL;
+ Buffer *buffer;
+
+ int i, type;
+ int *dimensions = 0, ndimensions = 0;
+
+ BPY_TRY(PyArg_ParseTuple(args, "iO|O", &type, &length_ob, &template));
+
+ if (type!=GL_BYTE && type!=GL_SHORT && type!=GL_INT && type!=GL_FLOAT) {
+ PyErr_SetString(PyExc_AttributeError, "type");
+ return NULL;
+ }
+
+ if (PyNumber_Check(length_ob)) {
+ ndimensions= 1;
+ dimensions= MEM_mallocN(ndimensions*sizeof(int), "Buffer dimensions");
+ dimensions[0]= PyInt_AsLong(length_ob);
+
+ } else if (PySequence_Check(length_ob)) {
+ ndimensions= PySequence_Length(length_ob);
+ dimensions= MEM_mallocN(ndimensions*sizeof(int), "Buffer dimensions");
+
+ for (i=0; i<ndimensions; i++) {
+ PyObject *ob= PySequence_GetItem(length_ob, i);
+
+ if (!PyNumber_Check(ob)) dimensions[i]= 1;
+ else dimensions[i]= PyInt_AsLong(ob);
+
+ Py_DECREF(ob);
+ }
+ }
+
+ buffer= make_buffer(type, ndimensions, dimensions);
+ if (template && ndimensions) {
+ if (Buffer_ass_slice((PyObject *) buffer, 0, dimensions[0], template)) {
+ Py_DECREF(buffer);
+ return NULL;
+ }
+ }
+
+ return (PyObject *) buffer;
+}
+
+/**********/
+
+
+/* Buffer sequence methods */
+
+static int Buffer_len(PyObject *self) {
+ Buffer *buf= (Buffer *) self;
+
+ return buf->dimensions[0];
+}
+
+static PyObject *Buffer_item(PyObject *self, int i) {
+ Buffer *buf= (Buffer *) self;
+
+ if (i >= buf->dimensions[0]) {
+ PyErr_SetString(PyExc_IndexError, "array index out of range");
+ return NULL;
+ }
+
+ if (buf->ndimensions==1) {
+ switch (buf->type) {
+ case GL_BYTE: return Py_BuildValue("b", buf->buf.asbyte[i]);
+ case GL_SHORT: return Py_BuildValue("h", buf->buf.asshort[i]);
+ case GL_INT: return Py_BuildValue("i", buf->buf.asint[i]);
+ case GL_FLOAT: return Py_BuildValue("f", buf->buf.asfloat[i]);
+ }
+ } else {
+ Buffer *newbuf;
+ int j, length, size;
+
+ length= 1;
+ for (j=1; j<buf->ndimensions; j++) {
+ length*= buf->dimensions[j];
+ }
+ size= type_size(buf->type);
+
+ newbuf= (Buffer *) PyObject_NEW(Buffer, &Buffer_Type);
+
+ Py_INCREF(self);
+ newbuf->parent= self;
+
+ newbuf->ndimensions= buf->ndimensions-1;
+ newbuf->type= buf->type;
+ newbuf->buf.asvoid= buf->buf.asbyte + i*length*size;
+
+ newbuf->dimensions= MEM_mallocN(newbuf->ndimensions*sizeof(int), "Buffer dimensions");
+ memcpy(newbuf->dimensions, buf->dimensions+1, newbuf->ndimensions*sizeof(int));
+
+ return (PyObject *) newbuf;
+ }
+
+ return NULL;
+}
+
+static PyObject *Buffer_slice(PyObject *self, int begin, int end)
+{
+ Buffer *buf= (Buffer *) self;
+ PyObject *list;
+ int count;
+
+ if (begin<0) begin= 0;
+ if (end>buf->dimensions[0]) end= buf->dimensions[0];
+ if (begin>end) begin= end;
+
+ list= PyList_New(end-begin);
+
+ for (count= begin; count<end; count++)
+ PyList_SetItem(list, count-begin, Buffer_item(self, count));
+
+ return list;
+}
+
+static int Buffer_ass_item(PyObject *self, int i, PyObject *v) {
+ Buffer *buf= (Buffer *) self;
+
+ if (i >= buf->dimensions[0]) {
+ PyErr_SetString(PyExc_IndexError, "array assignment index out of range");
+ return -1;
+ }
+
+ if (buf->ndimensions!=1) {
+ PyObject *row= Buffer_item(self, i);
+ int ret;
+
+ if (!row) return -1;
+
+ ret= Buffer_ass_slice(row, 0, buf->dimensions[1], v);
+ Py_DECREF(row);
+
+ return ret;
+ }
+
+ if (buf->type==GL_BYTE) {
+ if (!PyArg_Parse(v, "b;Coordinates must be ints", &buf->buf.asbyte[i]))
+ return -1;
+
+ } else if (buf->type==GL_SHORT) {
+ if (!PyArg_Parse(v, "h;Coordinates must be ints", &buf->buf.asshort[i]))
+ return -1;
+
+ } else if (buf->type==GL_INT) {
+ if (!PyArg_Parse(v, "i;Coordinates must be ints", &buf->buf.asint[i]))
+ return -1;
+
+ } else if (buf->type==GL_FLOAT) {
+ if (!PyArg_Parse(v, "f;Coordinates must be floats", &buf->buf.asfloat[i]))
+ return -1;
+ }
+
+ return 0;
+}
+
+static int Buffer_ass_slice(PyObject *self, int begin, int end, PyObject *seq)
+{
+ Buffer *buf= (Buffer *) self;
+ PyObject *item;
+ int count, err=0;
+
+ if (begin<0) begin= 0;
+ if (end>buf->dimensions[0]) end= buf->dimensions[0];
+ if (begin>end) begin= end;
+
+ if (!PySequence_Check(seq)) {
+ PyErr_SetString(PyExc_TypeError, "illegal argument type for built-in operation");
+ return -1;
+ }
+
+ if (PySequence_Length(seq)!=(end-begin)) {
+ PyErr_SetString(PyExc_TypeError, "size mismatch in assignment");
+ return -1;
+ }
+
+ for (count= begin; count<end; count++) {
+ item= PySequence_GetItem(seq, count-begin);
+ err= Buffer_ass_item(self, count, item);
+ Py_DECREF(item);
+
+ if (err) break;
+ }
+
+ return err;
+}
+static PySequenceMethods Buffer_SeqMethods = {
+ (inquiry) Buffer_len, /*sq_length*/
+ (binaryfunc) 0, /*sq_concat*/
+ (intargfunc) 0, /*sq_repeat*/
+ (intargfunc) Buffer_item, /*sq_item*/
+ (intintargfunc) Buffer_slice, /*sq_slice*/
+ (intobjargproc) Buffer_ass_item, /*sq_ass_item*/
+ (intintobjargproc) Buffer_ass_slice, /*sq_ass_slice*/
+};
+
+
+
+/**********/
+
+static void Buffer_dealloc(PyObject *self) {
+ Buffer *buf= (Buffer *) self;
+
+ if (buf->parent) Py_DECREF(buf->parent);
+ else MEM_freeN(buf->buf.asvoid);
+
+ MEM_freeN(buf->dimensions);
+
+ PyMem_DEL(self);
+}
+
+static PyObject *Buffer_tolist(PyObject *self) {
+ int i, len= ((Buffer *)self)->dimensions[0];
+ PyObject *list= PyList_New(len);
+
+ for (i=0; i<len; i++) {
+ PyList_SetItem(list, i, Buffer_item(self, i));
+ }
+
+ return list;
+}
+
+static PyObject *Buffer_dimensions(PyObject *self) {
+ Buffer *buffer= (Buffer *) self;
+ PyObject *list= PyList_New(buffer->ndimensions);
+ int i;
+
+ for (i= 0; i<buffer->ndimensions; i++) {
+ PyList_SetItem(list, i, PyInt_FromLong(buffer->dimensions[i]));
+ }
+
+ return list;
+}
+
+static PyObject *Buffer_getattr(PyObject *self, char *name) {
+ if (strcmp(name, "list")==0) return Buffer_tolist(self);
+ else if (strcmp(name, "dimensions")==0) return Buffer_dimensions(self);
+
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+}
+
+static PyObject *Buffer_repr(PyObject *self) {
+ PyObject *list= Buffer_tolist(self);
+ PyObject *repr= PyObject_Repr(list);
+ Py_DECREF(list);
+
+ return repr;
+}
+
+PyTypeObject Buffer_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "Buffer", /*tp_name*/
+ sizeof(Buffer), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ (destructor) Buffer_dealloc, /*tp_dealloc*/
+ (printfunc) 0, /*tp_print*/
+ (getattrfunc) Buffer_getattr, /*tp_getattr*/
+ (setattrfunc) 0, /*tp_setattr*/
+ (cmpfunc) 0, /*tp_compare*/
+ (reprfunc) Buffer_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &Buffer_SeqMethods, /*tp_as_sequence*/
+};
+
+#ifndef __APPLE__
+/* By golly George! It looks like fancy pants macro time!!! */
+
+/*
+#define int_str "i"
+#define int_var(number) bgl_int##number
+#define int_ref(number) &bgl_int##number
+#define int_def(number) int int_var(number)
+
+#define float_str "f"
+#define float_var(number) bgl_float##number
+#define float_ref(number) &bgl_float##number
+#define float_def(number) float float_var(number)
+*/
+
+/* TYPE_str is the string to pass to Py_ArgParse (for the format) */
+/* TYPE_var is the name to pass to the GL function */
+/* TYPE_ref is the pointer to pass to Py_ArgParse (to store in) */
+/* TYPE_def is the C initialization of the variable */
+
+#define void_str ""
+#define void_var(num)
+#define void_ref(num) &bgl_var##num
+#define void_def(num) char bgl_var##num
+
+#define buffer_str "O!"
+#define buffer_var(number) (bgl_buffer##number)->buf.asvoid
+#define buffer_ref(number) &Buffer_Type, &bgl_buffer##number
+#define buffer_def(number) Buffer *bgl_buffer##number
+
+/* GL Pointer fields, handled by buffer type */
+/* GLdoubleP, GLfloatP, GLintP, GLuintP, GLshortP */
+
+#define GLbooleanP_str "O!"
+#define GLbooleanP_var(number) (bgl_buffer##number)->buf.asvoid
+#define GLbooleanP_ref(number) &Buffer_Type, &bgl_buffer##number
+#define GLbooleanP_def(number) Buffer *bgl_buffer##number
+
+#define GLbyteP_str "O!"
+#define GLbyteP_var(number) (bgl_buffer##number)->buf.asvoid
+#define GLbyteP_ref(number) &Buffer_Type, &bgl_buffer##number
+#define GLbyteP_def(number) Buffer *bgl_buffer##number
+
+#define GLubyteP_str "O!"
+#define GLubyteP_var(number) (bgl_buffer##number)->buf.asvoid
+#define GLubyteP_ref(number) &Buffer_Type, &bgl_buffer##number
+#define GLubyteP_def(number) Buffer *bgl_buffer##number
+
+#define GLintP_str "O!"
+#define GLintP_var(number) (bgl_buffer##number)->buf.asvoid
+#define GLintP_ref(number) &Buffer_Type, &bgl_buffer##number
+#define GLintP_def(number) Buffer *bgl_buffer##number
+
+#define GLuintP_str "O!"
+#define GLuintP_var(number) (bgl_buffer##number)->buf.asvoid
+#define GLuintP_ref(number) &Buffer_Type, &bgl_buffer##number
+#define GLuintP_def(number) Buffer *bgl_buffer##number
+
+#define GLshortP_str "O!"
+#define GLshortP_var(number) (bgl_buffer##number)->buf.asvoid
+#define GLshortP_ref(number) &Buffer_Type, &bgl_buffer##number
+#define GLshortP_def(number) Buffer *bgl_buffer##number
+
+#define GLushortP_str "O!"
+#define GLushortP_var(number) (bgl_buffer##number)->buf.asvoid
+#define GLushortP_ref(number) &Buffer_Type, &bgl_buffer##number
+#define GLushortP_def(number) Buffer *bgl_buffer##number
+
+#define GLfloatP_str "O!"
+#define GLfloatP_var(number) (bgl_buffer##number)->buf.asvoid
+#define GLfloatP_ref(number) &Buffer_Type, &bgl_buffer##number
+#define GLfloatP_def(number) Buffer *bgl_buffer##number
+
+#define GLdoubleP_str "O!"
+#define GLdoubleP_var(number) (bgl_buffer##number)->buf.asvoid
+#define GLdoubleP_ref(number) &Buffer_Type, &bgl_buffer##number
+#define GLdoubleP_def(number) Buffer *bgl_buffer##number
+
+#define GLclampfP_str "O!"
+#define GLclampfP_var(number) (bgl_buffer##number)->buf.asvoid
+#define GLclampfP_ref(number) &Buffer_Type, &bgl_buffer##number
+#define GLclampfP_def(number) Buffer *bgl_buffer##number
+
+#define GLvoidP_str "O!"
+#define GLvoidP_var(number) (bgl_buffer##number)->buf.asvoid
+#define GLvoidP_ref(number) &Buffer_Type, &bgl_buffer##number
+#define GLvoidP_def(number) Buffer *bgl_buffer##number
+
+#define buffer_str "O!"
+#define buffer_var(number) (bgl_buffer##number)->buf.asvoid
+#define buffer_ref(number) &Buffer_Type, &bgl_buffer##number
+#define buffer_def(number) Buffer *bgl_buffer##number
+
+/* The standard GL typedefs are used as prototypes, we can't
+ * use the GL type directly because Py_ArgParse expects normal
+ * C types.
+ *
+ * Py_ArgParse doesn't grok writing into unsigned variables,
+ * so we use signed everything (even stuff that should be unsigned.
+ */
+
+/* typedef unsigned int GLenum; */
+#define GLenum_str "i"
+#define GLenum_var(num) bgl_var##num
+#define GLenum_ref(num) &bgl_var##num
+#define GLenum_def(num) /* unsigned */ int GLenum_var(num)
+
+/* typedef unsigned int GLboolean; */
+#define GLboolean_str "b"
+#define GLboolean_var(num) bgl_var##num
+#define GLboolean_ref(num) &bgl_var##num
+#define GLboolean_def(num) /* unsigned */ char GLboolean_var(num)
+
+/* typedef unsigned int GLbitfield; */
+#define GLbitfield_str "i"
+#define GLbitfield_var(num) bgl_var##num
+#define GLbitfield_ref(num) &bgl_var##num
+#define GLbitfield_def(num) /* unsigned */ int GLbitfield_var(num)
+
+/* typedef signed char GLbyte; */
+#define GLbyte_str "b"
+#define GLbyte_var(num) bgl_var##num
+#define GLbyte_ref(num) &bgl_var##num
+#define GLbyte_def(num) signed char GLbyte_var(num)
+
+/* typedef short GLshort; */
+#define GLshort_str "h"
+#define GLshort_var(num) bgl_var##num
+#define GLshort_ref(num) &bgl_var##num
+#define GLshort_def(num) short GLshort_var(num)
+
+/* typedef int GLint; */
+#define GLint_str "i"
+#define GLint_var(num) bgl_var##num
+#define GLint_ref(num) &bgl_var##num
+#define GLint_def(num) int GLint_var(num)
+
+/* typedef int GLsizei; */
+#define GLsizei_str "i"
+#define GLsizei_var(num) bgl_var##num
+#define GLsizei_ref(num) &bgl_var##num
+#define GLsizei_def(num) int GLsizei_var(num)
+
+/* typedef unsigned char GLubyte; */
+#define GLubyte_str "b"
+#define GLubyte_var(num) bgl_var##num
+#define GLubyte_ref(num) &bgl_var##num
+#define GLubyte_def(num) /* unsigned */ char GLubyte_var(num)
+
+/* typedef unsigned short GLushort; */
+#define GLushort_str "h"
+#define GLushort_var(num) bgl_var##num
+#define GLushort_ref(num) &bgl_var##num
+#define GLushort_def(num) /* unsigned */ short GLushort_var(num)
+
+/* typedef unsigned int GLuint; */
+#define GLuint_str "i"
+#define GLuint_var(num) bgl_var##num
+#define GLuint_ref(num) &bgl_var##num
+#define GLuint_def(num) /* unsigned */ int GLuint_var(num)
+
+/* typedef float GLfloat; */
+#define GLfloat_str "f"
+#define GLfloat_var(num) bgl_var##num
+#define GLfloat_ref(num) &bgl_var##num
+#define GLfloat_def(num) float GLfloat_var(num)
+
+/* typedef float GLclampf; */
+#define GLclampf_str "f"
+#define GLclampf_var(num) bgl_var##num
+#define GLclampf_ref(num) &bgl_var##num
+#define GLclampf_def(num) float GLclampf_var(num)
+
+/* typedef double GLdouble; */
+#define GLdouble_str "d"
+#define GLdouble_var(num) bgl_var##num
+#define GLdouble_ref(num) &bgl_var##num
+#define GLdouble_def(num) double GLdouble_var(num)
+
+/* typedef double GLclampd; */
+#define GLclampd_str "d"
+#define GLclampd_var(num) bgl_var##num
+#define GLclampd_ref(num) &bgl_var##num
+#define GLclampd_def(num) double GLclampd_var(num)
+
+/* typedef void GLvoid; */
+/* #define GLvoid_str "" */
+/* #define GLvoid_var(num) bgl_var##num */
+/* #define GLvoid_ref(num) &bgl_var##num */
+/* #define GLvoid_def(num) char bgl_var##num */
+
+#define arg_def1(a1) a1##_def(1)
+#define arg_def2(a1, a2) arg_def1(a1); a2##_def(2)
+#define arg_def3(a1, a2, a3) arg_def2(a1, a2); a3##_def(3)
+#define arg_def4(a1, a2, a3, a4) arg_def3(a1, a2, a3); a4##_def(4)
+#define arg_def5(a1, a2, a3, a4, a5) arg_def4(a1, a2, a3, a4); a5##_def(5)
+#define arg_def6(a1, a2, a3, a4, a5, a6)arg_def5(a1, a2, a3, a4, a5); a6##_def(6)
+#define arg_def7(a1, a2, a3, a4, a5, a6, a7)arg_def6(a1, a2, a3, a4, a5, a6); a7##_def(7)
+#define arg_def8(a1, a2, a3, a4, a5, a6, a7, a8)arg_def7(a1, a2, a3, a4, a5, a6, a7); a8##_def(8)
+#define arg_def9(a1, a2, a3, a4, a5, a6, a7, a8, a9)arg_def8(a1, a2, a3, a4, a5, a6, a7, a8); a9##_def(9)
+#define arg_def10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)arg_def9(a1, a2, a3, a4, a5, a6, a7, a8, a9); a10##_def(10)
+
+#define arg_var1(a1) a1##_var(1)
+#define arg_var2(a1, a2) arg_var1(a1), a2##_var(2)
+#define arg_var3(a1, a2, a3) arg_var2(a1, a2), a3##_var(3)
+#define arg_var4(a1, a2, a3, a4) arg_var3(a1, a2, a3), a4##_var(4)
+#define arg_var5(a1, a2, a3, a4, a5) arg_var4(a1, a2, a3, a4), a5##_var(5)
+#define arg_var6(a1, a2, a3, a4, a5, a6)arg_var5(a1, a2, a3, a4, a5), a6##_var(6)
+#define arg_var7(a1, a2, a3, a4, a5, a6, a7)arg_var6(a1, a2, a3, a4, a5, a6), a7##_var(7)
+#define arg_var8(a1, a2, a3, a4, a5, a6, a7, a8)arg_var7(a1, a2, a3, a4, a5, a6, a7), a8##_var(8)
+#define arg_var9(a1, a2, a3, a4, a5, a6, a7, a8, a9)arg_var8(a1, a2, a3, a4, a5, a6, a7, a8), a9##_var(9)
+#define arg_var10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)arg_var9(a1, a2, a3, a4, a5, a6, a7, a8, a9), a10##_var(10)
+
+#define arg_ref1(a1) a1##_ref(1)
+#define arg_ref2(a1, a2) arg_ref1(a1), a2##_ref(2)
+#define arg_ref3(a1, a2, a3) arg_ref2(a1, a2), a3##_ref(3)
+#define arg_ref4(a1, a2, a3, a4) arg_ref3(a1, a2, a3), a4##_ref(4)
+#define arg_ref5(a1, a2, a3, a4, a5) arg_ref4(a1, a2, a3, a4), a5##_ref(5)
+#define arg_ref6(a1, a2, a3, a4, a5, a6)arg_ref5(a1, a2, a3, a4, a5), a6##_ref(6)
+#define arg_ref7(a1, a2, a3, a4, a5, a6, a7)arg_ref6(a1, a2, a3, a4, a5, a6), a7##_ref(7)
+#define arg_ref8(a1, a2, a3, a4, a5, a6, a7, a8)arg_ref7(a1, a2, a3, a4, a5, a6, a7), a8##_ref(8)
+#define arg_ref9(a1, a2, a3, a4, a5, a6, a7, a8, a9)arg_ref8(a1, a2, a3, a4, a5, a6, a7, a8), a9##_ref(9)
+#define arg_ref10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)arg_ref9(a1, a2, a3, a4, a5, a6, a7, a8, a9), a10##_ref(10)
+
+#define arg_str1(a1) a1##_str
+#define arg_str2(a1, a2) arg_str1(a1) a2##_str
+#define arg_str3(a1, a2, a3) arg_str2(a1, a2) a3##_str
+#define arg_str4(a1, a2, a3, a4) arg_str3(a1, a2, a3) a4##_str
+#define arg_str5(a1, a2, a3, a4, a5) arg_str4(a1, a2, a3, a4) a5##_str
+#define arg_str6(a1, a2, a3, a4, a5, a6)arg_str5(a1, a2, a3, a4, a5) a6##_str
+#define arg_str7(a1, a2, a3, a4, a5, a6, a7)arg_str6(a1, a2, a3, a4, a5, a6) a7##_str
+#define arg_str8(a1, a2, a3, a4, a5, a6, a7, a8)arg_str7(a1, a2, a3, a4, a5, a6, a7) a8##_str
+#define arg_str9(a1, a2, a3, a4, a5, a6, a7, a8, a9)arg_str8(a1, a2, a3, a4, a5, a6, a7, a8) a9##_str
+#define arg_str10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10)arg_str9(a1, a2, a3, a4, a5, a6, a7, a8, a9) a10##_str
+
+#define ret_def_void
+#define ret_set_void
+#define ret_ret_void return BPY_incr_ret(Py_None)
+
+#define ret_def_GLint int ret_int
+#define ret_set_GLint ret_int=
+#define ret_ret_GLint return PyInt_FromLong(ret_int);
+
+#define ret_def_GLuint unsigned int ret_uint
+#define ret_set_GLuint ret_uint=
+#define ret_ret_GLuint return PyInt_FromLong((long) ret_uint);
+
+#define ret_def_GLenum unsigned int ret_uint
+#define ret_set_GLenum ret_uint=
+#define ret_ret_GLenum return PyInt_FromLong((long) ret_uint);
+
+#define ret_def_GLboolean unsigned char ret_bool
+#define ret_set_GLboolean ret_bool=
+#define ret_ret_GLboolean return PyInt_FromLong((long) ret_bool);
+
+#define ret_def_GLstring const unsigned char *ret_str;
+#define ret_set_GLstring ret_str=
+#define ret_ret_GLstring return PyString_FromString(ret_str);
+
+#define BGL_Wrap(nargs, funcname, ret, arg_list) \
+static PyObject *Method_##funcname (PyObject *self, PyObject *args) {\
+ arg_def##nargs arg_list; \
+ ret_def_##ret; \
+ if(!PyArg_ParseTuple(args, arg_str##nargs arg_list, arg_ref##nargs arg_list)) return NULL;\
+ ret_set_##ret gl##funcname (arg_var##nargs arg_list);\
+ ret_ret_##ret; \
+}
+
+BGL_Wrap(2, Accum, void, (GLenum, GLfloat))
+BGL_Wrap(2, AlphaFunc, void, (GLenum, GLclampf))
+BGL_Wrap(3, AreTexturesResident, GLboolean, (GLsizei, GLuintP, GLbooleanP))
+BGL_Wrap(1, Begin, void, (GLenum))
+BGL_Wrap(2, BindTexture, void, (GLenum, GLuint))
+BGL_Wrap(7, Bitmap, void, (GLsizei, GLsizei, GLfloat, GLfloat, GLfloat, GLfloat, GLubyteP))
+BGL_Wrap(2, BlendFunc, void, (GLenum, GLenum))
+BGL_Wrap(1, CallList, void, (GLuint))
+BGL_Wrap(3, CallLists, void, (GLsizei, GLenum, GLvoidP))
+BGL_Wrap(1, Clear, void, (GLbitfield))
+BGL_Wrap(4, ClearAccum, void, (GLfloat, GLfloat, GLfloat, GLfloat))
+BGL_Wrap(4, ClearColor, void, (GLclampf, GLclampf, GLclampf, GLclampf))
+BGL_Wrap(1, ClearDepth, void, (GLclampd))
+BGL_Wrap(1, ClearIndex, void, (GLfloat))
+BGL_Wrap(1, ClearStencil, void, (GLint))
+BGL_Wrap(2, ClipPlane, void, (GLenum, GLdoubleP))
+BGL_Wrap(3, Color3b, void, (GLbyte, GLbyte, GLbyte))
+BGL_Wrap(1, Color3bv, void, (GLbyteP))
+BGL_Wrap(3, Color3d, void, (GLdouble, GLdouble, GLdouble))
+BGL_Wrap(1, Color3dv, void, (GLdoubleP))
+BGL_Wrap(3, Color3f, void, (GLfloat, GLfloat, GLfloat))
+BGL_Wrap(1, Color3fv, void, (GLfloatP))
+BGL_Wrap(3, Color3i, void, (GLint, GLint, GLint))
+BGL_Wrap(1, Color3iv, void, (GLintP))
+BGL_Wrap(3, Color3s, void, (GLshort, GLshort, GLshort))
+BGL_Wrap(1, Color3sv, void, (GLshortP))
+BGL_Wrap(3, Color3ub, void, (GLubyte, GLubyte, GLubyte))
+BGL_Wrap(1, Color3ubv, void, (GLubyteP))
+BGL_Wrap(3, Color3ui, void, (GLuint, GLuint, GLuint))
+BGL_Wrap(1, Color3uiv, void, (GLuintP))
+BGL_Wrap(3, Color3us, void, (GLushort, GLushort, GLushort))
+BGL_Wrap(1, Color3usv, void, (GLushortP))
+BGL_Wrap(4, Color4b, void, (GLbyte, GLbyte, GLbyte, GLbyte))
+BGL_Wrap(1, Color4bv, void, (GLbyteP))
+BGL_Wrap(4, Color4d, void, (GLdouble, GLdouble, GLdouble, GLdouble))
+BGL_Wrap(1, Color4dv, void, (GLdoubleP))
+BGL_Wrap(4, Color4f, void, (GLfloat, GLfloat, GLfloat, GLfloat))
+BGL_Wrap(1, Color4fv, void, (GLfloatP))
+BGL_Wrap(4, Color4i, void, (GLint, GLint, GLint, GLint))
+BGL_Wrap(1, Color4iv, void, (GLintP))
+BGL_Wrap(4, Color4s, void, (GLshort, GLshort, GLshort, GLshort))
+BGL_Wrap(1, Color4sv, void, (GLshortP))
+BGL_Wrap(4, Color4ub, void, (GLubyte, GLubyte, GLubyte, GLubyte))
+BGL_Wrap(1, Color4ubv, void, (GLubyteP))
+BGL_Wrap(4, Color4ui, void, (GLuint, GLuint, GLuint, GLuint))
+BGL_Wrap(1, Color4uiv, void, (GLuintP))
+BGL_Wrap(4, Color4us, void, (GLushort, GLushort, GLushort, GLushort))
+BGL_Wrap(1, Color4usv, void, (GLushortP))
+BGL_Wrap(4, ColorMask, void, (GLboolean, GLboolean, GLboolean, GLboolean))
+BGL_Wrap(2, ColorMaterial, void, (GLenum, GLenum))
+BGL_Wrap(5, CopyPixels, void, (GLint, GLint, GLsizei, GLsizei, GLenum))
+BGL_Wrap(1, CullFace, void, (GLenum))
+BGL_Wrap(2, DeleteLists, void, (GLuint, GLsizei))
+BGL_Wrap(2, DeleteTextures, void, (GLsizei, GLuintP))
+BGL_Wrap(1, DepthFunc, void, (GLenum))
+BGL_Wrap(1, DepthMask, void, (GLboolean))
+BGL_Wrap(2, DepthRange, void, (GLclampd, GLclampd))
+BGL_Wrap(1, Disable, void, (GLenum))
+BGL_Wrap(1, DrawBuffer, void, (GLenum))
+BGL_Wrap(5, DrawPixels, void, (GLsizei, GLsizei, GLenum, GLenum, GLvoidP))
+BGL_Wrap(1, EdgeFlag, void, (GLboolean))
+BGL_Wrap(1, EdgeFlagv, void, (GLbooleanP))
+BGL_Wrap(1, Enable, void, (GLenum))
+BGL_Wrap(1, End, void, (void))
+BGL_Wrap(1, EndList, void, (void))
+BGL_Wrap(1, EvalCoord1d, void, (GLdouble))
+BGL_Wrap(1, EvalCoord1dv, void, (GLdoubleP))
+BGL_Wrap(1, EvalCoord1f, void, (GLfloat))
+BGL_Wrap(1, EvalCoord1fv, void, (GLfloatP))
+BGL_Wrap(2, EvalCoord2d, void, (GLdouble, GLdouble))
+BGL_Wrap(1, EvalCoord2dv, void, (GLdoubleP))
+BGL_Wrap(2, EvalCoord2f, void, (GLfloat, GLfloat))
+BGL_Wrap(1, EvalCoord2fv, void, (GLfloatP))
+BGL_Wrap(3, EvalMesh1, void, (GLenum, GLint, GLint))
+BGL_Wrap(5, EvalMesh2, void, (GLenum, GLint, GLint, GLint, GLint))
+BGL_Wrap(1, EvalPoint1, void, (GLint))
+BGL_Wrap(2, EvalPoint2, void, (GLint, GLint))
+BGL_Wrap(3, FeedbackBuffer, void, (GLsizei, GLenum, GLfloatP))
+BGL_Wrap(1, Finish, void, (void))
+BGL_Wrap(1, Flush, void, (void))
+BGL_Wrap(2, Fogf, void, (GLenum, GLfloat))
+BGL_Wrap(2, Fogfv, void, (GLenum, GLfloatP))
+BGL_Wrap(2, Fogi, void, (GLenum, GLint))
+BGL_Wrap(2, Fogiv, void, (GLenum, GLintP))
+BGL_Wrap(1, FrontFace, void, (GLenum))
+BGL_Wrap(6, Frustum, void, (GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble))
+BGL_Wrap(1, GenLists, GLuint, (GLsizei))
+BGL_Wrap(2, GenTextures, void, (GLsizei, GLuintP))
+BGL_Wrap(2, GetBooleanv, void, (GLenum, GLbooleanP))
+BGL_Wrap(2, GetClipPlane, void, (GLenum, GLdoubleP))
+BGL_Wrap(2, GetDoublev, void, (GLenum, GLdoubleP))
+BGL_Wrap(1, GetError, GLenum, (void))
+BGL_Wrap(2, GetFloatv, void, (GLenum, GLfloatP))
+BGL_Wrap(2, GetIntegerv, void, (GLenum, GLintP))
+BGL_Wrap(3, GetLightfv, void, (GLenum, GLenum, GLfloatP))
+BGL_Wrap(3, GetLightiv, void, (GLenum, GLenum, GLintP))
+BGL_Wrap(3, GetMapdv, void, (GLenum, GLenum, GLdoubleP))
+BGL_Wrap(3, GetMapfv, void, (GLenum, GLenum, GLfloatP))
+BGL_Wrap(3, GetMapiv, void, (GLenum, GLenum, GLintP))
+BGL_Wrap(3, GetMaterialfv, void, (GLenum, GLenum, GLfloatP))
+BGL_Wrap(3, GetMaterialiv, void, (GLenum, GLenum, GLintP))
+BGL_Wrap(2, GetPixelMapfv, void, (GLenum, GLfloatP))
+BGL_Wrap(2, GetPixelMapuiv, void, (GLenum, GLuintP))
+BGL_Wrap(2, GetPixelMapusv, void, (GLenum, GLushortP))
+BGL_Wrap(1, GetPolygonStipple, void, (GLubyteP))
+BGL_Wrap(1, GetString, GLstring, (GLenum))
+BGL_Wrap(3, GetTexEnvfv, void, (GLenum, GLenum, GLfloatP))
+BGL_Wrap(3, GetTexEnviv, void, (GLenum, GLenum, GLintP))
+BGL_Wrap(3, GetTexGendv, void, (GLenum, GLenum, GLdoubleP))
+BGL_Wrap(3, GetTexGenfv, void, (GLenum, GLenum, GLfloatP))
+BGL_Wrap(3, GetTexGeniv, void, (GLenum, GLenum, GLintP))
+BGL_Wrap(5, GetTexImage, void, (GLenum, GLint, GLenum, GLenum, GLvoidP))
+BGL_Wrap(4, GetTexLevelParameterfv, void, (GLenum, GLint, GLenum, GLfloatP))
+BGL_Wrap(4, GetTexLevelParameteriv, void, (GLenum, GLint, GLenum, GLintP))
+BGL_Wrap(3, GetTexParameterfv, void, (GLenum, GLenum, GLfloatP))
+BGL_Wrap(3, GetTexParameteriv, void, (GLenum, GLenum, GLintP))
+BGL_Wrap(2, Hint, void, (GLenum, GLenum))
+BGL_Wrap(1, IndexMask, void, (GLuint))
+BGL_Wrap(1, Indexd, void, (GLdouble))
+BGL_Wrap(1, Indexdv, void, (GLdoubleP))
+BGL_Wrap(1, Indexf, void, (GLfloat))
+BGL_Wrap(1, Indexfv, void, (GLfloatP))
+BGL_Wrap(1, Indexi, void, (GLint))
+BGL_Wrap(1, Indexiv, void, (GLintP))
+BGL_Wrap(1, Indexs, void, (GLshort))
+BGL_Wrap(1, Indexsv, void, (GLshortP))
+BGL_Wrap(1, InitNames, void, (void))
+BGL_Wrap(1, IsEnabled, GLboolean, (GLenum))
+BGL_Wrap(1, IsList, GLboolean, (GLuint))
+BGL_Wrap(1, IsTexture, GLboolean, (GLuint))
+BGL_Wrap(2, LightModelf, void, (GLenum, GLfloat))
+BGL_Wrap(2, LightModelfv, void, (GLenum, GLfloatP))
+BGL_Wrap(2, LightModeli, void, (GLenum, GLint))
+BGL_Wrap(2, LightModeliv, void, (GLenum, GLintP))
+BGL_Wrap(3, Lightf, void, (GLenum, GLenum, GLfloat))
+BGL_Wrap(3, Lightfv, void, (GLenum, GLenum, GLfloatP))
+BGL_Wrap(3, Lighti, void, (GLenum, GLenum, GLint))
+BGL_Wrap(3, Lightiv, void, (GLenum, GLenum, GLintP))
+BGL_Wrap(2, LineStipple, void, (GLint, GLushort))
+BGL_Wrap(1, LineWidth, void, (GLfloat))
+BGL_Wrap(1, ListBase, void, (GLuint))
+BGL_Wrap(1, LoadIdentity, void, (void))
+BGL_Wrap(1, LoadMatrixd, void, (GLdoubleP))
+BGL_Wrap(1, LoadMatrixf, void, (GLfloatP))
+BGL_Wrap(1, LoadName, void, (GLuint))
+BGL_Wrap(1, LogicOp, void, (GLenum))
+BGL_Wrap(6, Map1d, void, (GLenum, GLdouble, GLdouble, GLint, GLint, GLdoubleP))
+BGL_Wrap(6, Map1f, void, (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloatP))
+BGL_Wrap(10, Map2d, void, (GLenum, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, GLdoubleP))
+BGL_Wrap(10, Map2f, void, (GLenum, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, GLfloatP))
+BGL_Wrap(3, MapGrid1d, void, (GLint, GLdouble, GLdouble))
+BGL_Wrap(3, MapGrid1f, void, (GLint, GLfloat, GLfloat))
+BGL_Wrap(6, MapGrid2d, void, (GLint, GLdouble, GLdouble, GLint, GLdouble, GLdouble))
+BGL_Wrap(6, MapGrid2f, void, (GLint, GLfloat, GLfloat, GLint, GLfloat, GLfloat))
+BGL_Wrap(3, Materialf, void, (GLenum, GLenum, GLfloat))
+BGL_Wrap(3, Materialfv, void, (GLenum, GLenum, GLfloatP))
+BGL_Wrap(3, Materiali, void, (GLenum, GLenum, GLint))
+BGL_Wrap(3, Materialiv, void, (GLenum, GLenum, GLintP))
+BGL_Wrap(1, MatrixMode, void, (GLenum))
+BGL_Wrap(1, MultMatrixd, void, (GLdoubleP))
+BGL_Wrap(1, MultMatrixf, void, (GLfloatP))
+BGL_Wrap(2, NewList, void, (GLuint, GLenum))
+BGL_Wrap(3, Normal3b, void, (GLbyte, GLbyte, GLbyte))
+BGL_Wrap(1, Normal3bv, void, (GLbyteP))
+BGL_Wrap(3, Normal3d, void, (GLdouble, GLdouble, GLdouble))
+BGL_Wrap(1, Normal3dv, void, (GLdoubleP))
+BGL_Wrap(3, Normal3f, void, (GLfloat, GLfloat, GLfloat))
+BGL_Wrap(1, Normal3fv, void, (GLfloatP))
+BGL_Wrap(3, Normal3i, void, (GLint, GLint, GLint))
+BGL_Wrap(1, Normal3iv, void, (GLintP))
+BGL_Wrap(3, Normal3s, void, (GLshort, GLshort, GLshort))
+BGL_Wrap(1, Normal3sv, void, (GLshortP))
+BGL_Wrap(6, Ortho, void, (GLdouble, GLdouble, GLdouble, GLdouble, GLdouble, GLdouble))
+BGL_Wrap(1, PassThrough, void, (GLfloat))
+BGL_Wrap(3, PixelMapfv, void, (GLenum, GLint, GLfloatP))
+BGL_Wrap(3, PixelMapuiv, void, (GLenum, GLint, GLuintP))
+BGL_Wrap(3, PixelMapusv, void, (GLenum, GLint, GLushortP))
+BGL_Wrap(2, PixelStoref, void, (GLenum, GLfloat))
+BGL_Wrap(2, PixelStorei, void, (GLenum, GLint))
+BGL_Wrap(2, PixelTransferf, void, (GLenum, GLfloat))
+BGL_Wrap(2, PixelTransferi, void, (GLenum, GLint))
+BGL_Wrap(2, PixelZoom, void, (GLfloat, GLfloat))
+BGL_Wrap(1, PointSize, void, (GLfloat))
+BGL_Wrap(2, PolygonMode, void, (GLenum, GLenum))
+BGL_Wrap(2, PolygonOffset, void, (GLfloat, GLfloat))
+BGL_Wrap(1, PolygonStipple, void, (GLubyteP))
+BGL_Wrap(1, PopAttrib, void, (void))
+BGL_Wrap(1, PopMatrix, void, (void))
+BGL_Wrap(1, PopName, void, (void))
+BGL_Wrap(3, PrioritizeTextures, void, (GLsizei, GLuintP, GLclampfP))
+BGL_Wrap(1, PushAttrib, void, (GLbitfield))
+BGL_Wrap(1, PushMatrix, void, (void))
+BGL_Wrap(1, PushName, void, (GLuint))
+BGL_Wrap(2, RasterPos2d, void, (GLdouble, GLdouble))
+BGL_Wrap(1, RasterPos2dv, void, (GLdoubleP))
+BGL_Wrap(2, RasterPos2f, void, (GLfloat, GLfloat))
+BGL_Wrap(1, RasterPos2fv, void, (GLfloatP))
+BGL_Wrap(2, RasterPos2i, void, (GLint, GLint))
+BGL_Wrap(1, RasterPos2iv, void, (GLintP))
+BGL_Wrap(2, RasterPos2s, void, (GLshort, GLshort))
+BGL_Wrap(1, RasterPos2sv, void, (GLshortP))
+BGL_Wrap(3, RasterPos3d, void, (GLdouble, GLdouble, GLdouble))
+BGL_Wrap(1, RasterPos3dv, void, (GLdoubleP))
+BGL_Wrap(3, RasterPos3f, void, (GLfloat, GLfloat, GLfloat))
+BGL_Wrap(1, RasterPos3fv, void, (GLfloatP))
+BGL_Wrap(3, RasterPos3i, void, (GLint, GLint, GLint))
+BGL_Wrap(1, RasterPos3iv, void, (GLintP))
+BGL_Wrap(3, RasterPos3s, void, (GLshort, GLshort, GLshort))
+BGL_Wrap(1, RasterPos3sv, void, (GLshortP))
+BGL_Wrap(4, RasterPos4d, void, (GLdouble, GLdouble, GLdouble, GLdouble))
+BGL_Wrap(1, RasterPos4dv, void, (GLdoubleP))
+BGL_Wrap(4, RasterPos4f, void, (GLfloat, GLfloat, GLfloat, GLfloat))
+BGL_Wrap(1, RasterPos4fv, void, (GLfloatP))
+BGL_Wrap(4, RasterPos4i, void, (GLint, GLint, GLint, GLint))
+BGL_Wrap(1, RasterPos4iv, void, (GLintP))
+BGL_Wrap(4, RasterPos4s, void, (GLshort, GLshort, GLshort, GLshort))
+BGL_Wrap(1, RasterPos4sv, void, (GLshortP))
+BGL_Wrap(1, ReadBuffer, void, (GLenum))
+BGL_Wrap(7, ReadPixels, void, (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoidP))
+BGL_Wrap(4, Rectd, void, (GLdouble, GLdouble, GLdouble, GLdouble))
+BGL_Wrap(2, Rectdv, void, (GLdoubleP, GLdoubleP))
+BGL_Wrap(4, Rectf, void, (GLfloat, GLfloat, GLfloat, GLfloat))
+BGL_Wrap(2, Rectfv, void, (GLfloatP, GLfloatP))
+BGL_Wrap(4, Recti, void, (GLint, GLint, GLint, GLint))
+BGL_Wrap(2, Rectiv, void, (GLintP, GLintP))
+BGL_Wrap(4, Rects, void, (GLshort, GLshort, GLshort, GLshort))
+BGL_Wrap(2, Rectsv, void, (GLshortP, GLshortP))
+BGL_Wrap(1, RenderMode, GLint, (GLenum))
+BGL_Wrap(4, Rotated, void, (GLdouble, GLdouble, GLdouble, GLdouble))
+BGL_Wrap(4, Rotatef, void, (GLfloat, GLfloat, GLfloat, GLfloat))
+BGL_Wrap(3, Scaled, void, (GLdouble, GLdouble, GLdouble))
+BGL_Wrap(3, Scalef, void, (GLfloat, GLfloat, GLfloat))
+BGL_Wrap(4, Scissor, void, (GLint, GLint, GLsizei, GLsizei))
+BGL_Wrap(2, SelectBuffer, void, (GLsizei, GLuintP))
+BGL_Wrap(1, ShadeModel, void, (GLenum))
+BGL_Wrap(3, StencilFunc, void, (GLenum, GLint, GLuint))
+BGL_Wrap(1, StencilMask, void, (GLuint))
+BGL_Wrap(3, StencilOp, void, (GLenum, GLenum, GLenum))
+BGL_Wrap(1, TexCoord1d, void, (GLdouble))
+BGL_Wrap(1, TexCoord1dv, void, (GLdoubleP))
+BGL_Wrap(1, TexCoord1f, void, (GLfloat))
+BGL_Wrap(1, TexCoord1fv, void, (GLfloatP))
+BGL_Wrap(1, TexCoord1i, void, (GLint))
+BGL_Wrap(1, TexCoord1iv, void, (GLintP))
+BGL_Wrap(1, TexCoord1s, void, (GLshort))
+BGL_Wrap(1, TexCoord1sv, void, (GLshortP))
+BGL_Wrap(2, TexCoord2d, void, (GLdouble, GLdouble))
+BGL_Wrap(1, TexCoord2dv, void, (GLdoubleP))
+BGL_Wrap(2, TexCoord2f, void, (GLfloat, GLfloat))
+BGL_Wrap(1, TexCoord2fv, void, (GLfloatP))
+BGL_Wrap(2, TexCoord2i, void, (GLint, GLint))
+BGL_Wrap(1, TexCoord2iv, void, (GLintP))
+BGL_Wrap(2, TexCoord2s, void, (GLshort, GLshort))
+BGL_Wrap(1, TexCoord2sv, void, (GLshortP))
+BGL_Wrap(3, TexCoord3d, void, (GLdouble, GLdouble, GLdouble))
+BGL_Wrap(1, TexCoord3dv, void, (GLdoubleP))
+BGL_Wrap(3, TexCoord3f, void, (GLfloat, GLfloat, GLfloat))
+BGL_Wrap(1, TexCoord3fv, void, (GLfloatP))
+BGL_Wrap(3, TexCoord3i, void, (GLint, GLint, GLint))
+BGL_Wrap(1, TexCoord3iv, void, (GLintP))
+BGL_Wrap(3, TexCoord3s, void, (GLshort, GLshort, GLshort))
+BGL_Wrap(1, TexCoord3sv, void, (GLshortP))
+BGL_Wrap(4, TexCoord4d, void, (GLdouble, GLdouble, GLdouble, GLdouble))
+BGL_Wrap(1, TexCoord4dv, void, (GLdoubleP))
+BGL_Wrap(4, TexCoord4f, void, (GLfloat, GLfloat, GLfloat, GLfloat))
+BGL_Wrap(1, TexCoord4fv, void, (GLfloatP))
+BGL_Wrap(4, TexCoord4i, void, (GLint, GLint, GLint, GLint))
+BGL_Wrap(1, TexCoord4iv, void, (GLintP))
+BGL_Wrap(4, TexCoord4s, void, (GLshort, GLshort, GLshort, GLshort))
+BGL_Wrap(1, TexCoord4sv, void, (GLshortP))
+BGL_Wrap(3, TexEnvf, void, (GLenum, GLenum, GLfloat))
+BGL_Wrap(3, TexEnvfv, void, (GLenum, GLenum, GLfloatP))
+BGL_Wrap(3, TexEnvi, void, (GLenum, GLenum, GLint))
+BGL_Wrap(3, TexEnviv, void, (GLenum, GLenum, GLintP))
+BGL_Wrap(3, TexGend, void, (GLenum, GLenum, GLdouble))
+BGL_Wrap(3, TexGendv, void, (GLenum, GLenum, GLdoubleP))
+BGL_Wrap(3, TexGenf, void, (GLenum, GLenum, GLfloat))
+BGL_Wrap(3, TexGenfv, void, (GLenum, GLenum, GLfloatP))
+BGL_Wrap(3, TexGeni, void, (GLenum, GLenum, GLint))
+BGL_Wrap(3, TexGeniv, void, (GLenum, GLenum, GLintP))
+BGL_Wrap(8, TexImage1D, void, (GLenum, GLint, GLint, GLsizei, GLint, GLenum, GLenum, GLvoidP))
+BGL_Wrap(9, TexImage2D, void, (GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, GLvoidP))
+BGL_Wrap(3, TexParameterf, void, (GLenum, GLenum, GLfloat))
+BGL_Wrap(3, TexParameterfv, void, (GLenum, GLenum, GLfloatP))
+BGL_Wrap(3, TexParameteri, void, (GLenum, GLenum, GLint))
+BGL_Wrap(3, TexParameteriv, void, (GLenum, GLenum, GLintP))
+BGL_Wrap(3, Translated, void, (GLdouble, GLdouble, GLdouble))
+BGL_Wrap(3, Translatef, void, (GLfloat, GLfloat, GLfloat))
+BGL_Wrap(2, Vertex2d, void, (GLdouble, GLdouble))
+BGL_Wrap(1, Vertex2dv, void, (GLdoubleP))
+BGL_Wrap(2, Vertex2f, void, (GLfloat, GLfloat))
+BGL_Wrap(1, Vertex2fv, void, (GLfloatP))
+BGL_Wrap(2, Vertex2i, void, (GLint, GLint))
+BGL_Wrap(1, Vertex2iv, void, (GLintP))
+BGL_Wrap(2, Vertex2s, void, (GLshort, GLshort))
+BGL_Wrap(1, Vertex2sv, void, (GLshortP))
+BGL_Wrap(3, Vertex3d, void, (GLdouble, GLdouble, GLdouble))
+BGL_Wrap(1, Vertex3dv, void, (GLdoubleP))
+BGL_Wrap(3, Vertex3f, void, (GLfloat, GLfloat, GLfloat))
+BGL_Wrap(1, Vertex3fv, void, (GLfloatP))
+BGL_Wrap(3, Vertex3i, void, (GLint, GLint, GLint))
+BGL_Wrap(1, Vertex3iv, void, (GLintP))
+BGL_Wrap(3, Vertex3s, void, (GLshort, GLshort, GLshort))
+BGL_Wrap(1, Vertex3sv, void, (GLshortP))
+BGL_Wrap(4, Vertex4d, void, (GLdouble, GLdouble, GLdouble, GLdouble))
+BGL_Wrap(1, Vertex4dv, void, (GLdoubleP))
+BGL_Wrap(4, Vertex4f, void, (GLfloat, GLfloat, GLfloat, GLfloat))
+BGL_Wrap(1, Vertex4fv, void, (GLfloatP))
+BGL_Wrap(4, Vertex4i, void, (GLint, GLint, GLint, GLint))
+BGL_Wrap(1, Vertex4iv, void, (GLintP))
+BGL_Wrap(4, Vertex4s, void, (GLshort, GLshort, GLshort, GLshort))
+BGL_Wrap(1, Vertex4sv, void, (GLshortP))
+BGL_Wrap(4, Viewport, void, (GLint, GLint, GLsizei, GLsizei))
+#endif
+
+/* XXX */
+#undef MethodDef
+#define MethodDef(func) {"gl"#func, Method_##func, METH_VARARGS}
+
+static struct PyMethodDef BGL_methods[] = {
+ {"Buffer", Method_Buffer, METH_VARARGS, Method_Buffer_doc},
+#ifndef __APPLE__
+ MethodDef( Accum),
+ MethodDef( AlphaFunc),
+ MethodDef( AreTexturesResident),
+ MethodDef( Begin),
+ MethodDef( BindTexture),
+ MethodDef( Bitmap),
+ MethodDef( BlendFunc),
+ MethodDef( CallList),
+ MethodDef( CallLists),
+ MethodDef( Clear),
+ MethodDef( ClearAccum),
+ MethodDef( ClearColor),
+ MethodDef( ClearDepth),
+ MethodDef( ClearIndex),
+ MethodDef( ClearStencil),
+ MethodDef( ClipPlane),
+ MethodDef( Color3b),
+ MethodDef( Color3bv),
+ MethodDef( Color3d),
+ MethodDef( Color3dv),
+ MethodDef( Color3f),
+ MethodDef( Color3fv),
+ MethodDef( Color3i),
+ MethodDef( Color3iv),
+ MethodDef( Color3s),
+ MethodDef( Color3sv),
+ MethodDef( Color3ub),
+ MethodDef( Color3ubv),
+ MethodDef( Color3ui),
+ MethodDef( Color3uiv),
+ MethodDef( Color3us),
+ MethodDef( Color3usv),
+ MethodDef( Color4b),
+ MethodDef( Color4bv),
+ MethodDef( Color4d),
+ MethodDef( Color4dv),
+ MethodDef( Color4f),
+ MethodDef( Color4fv),
+ MethodDef( Color4i),
+ MethodDef( Color4iv),
+ MethodDef( Color4s),
+ MethodDef( Color4sv),
+ MethodDef( Color4ub),
+ MethodDef( Color4ubv),
+ MethodDef( Color4ui),
+ MethodDef( Color4uiv),
+ MethodDef( Color4us),
+ MethodDef( Color4usv),
+ MethodDef( ColorMask),
+ MethodDef( ColorMaterial),
+ MethodDef( CopyPixels),
+ MethodDef( CullFace),
+ MethodDef( DeleteLists),
+ MethodDef( DeleteTextures),
+ MethodDef( DepthFunc),
+ MethodDef( DepthMask),
+ MethodDef( DepthRange),
+ MethodDef( Disable),
+ MethodDef( DrawBuffer),
+ MethodDef( DrawPixels),
+ MethodDef( EdgeFlag),
+ MethodDef( EdgeFlagv),
+ MethodDef( Enable),
+ MethodDef( End),
+ MethodDef( EndList),
+ MethodDef( EvalCoord1d),
+ MethodDef( EvalCoord1dv),
+ MethodDef( EvalCoord1f),
+ MethodDef( EvalCoord1fv),
+ MethodDef( EvalCoord2d),
+ MethodDef( EvalCoord2dv),
+ MethodDef( EvalCoord2f),
+ MethodDef( EvalCoord2fv),
+ MethodDef( EvalMesh1),
+ MethodDef( EvalMesh2),
+ MethodDef( EvalPoint1),
+ MethodDef( EvalPoint2),
+ MethodDef( FeedbackBuffer),
+ MethodDef( Finish),
+ MethodDef( Flush),
+ MethodDef( Fogf),
+ MethodDef( Fogfv),
+ MethodDef( Fogi),
+ MethodDef( Fogiv),
+ MethodDef( FrontFace),
+ MethodDef( Frustum),
+ MethodDef( GenLists),
+ MethodDef( GenTextures),
+ MethodDef( GetBooleanv),
+ MethodDef( GetClipPlane),
+ MethodDef( GetDoublev),
+ MethodDef( GetError),
+ MethodDef( GetFloatv),
+ MethodDef( GetIntegerv),
+ MethodDef( GetLightfv),
+ MethodDef( GetLightiv),
+ MethodDef( GetMapdv),
+ MethodDef( GetMapfv),
+ MethodDef( GetMapiv),
+ MethodDef( GetMaterialfv),
+ MethodDef( GetMaterialiv),
+ MethodDef( GetPixelMapfv),
+ MethodDef( GetPixelMapuiv),
+ MethodDef( GetPixelMapusv),
+ MethodDef( GetPolygonStipple),
+ MethodDef( GetString),
+ MethodDef( GetTexEnvfv),
+ MethodDef( GetTexEnviv),
+ MethodDef( GetTexGendv),
+ MethodDef( GetTexGenfv),
+ MethodDef( GetTexGeniv),
+ MethodDef( GetTexImage),
+ MethodDef( GetTexLevelParameterfv),
+ MethodDef( GetTexLevelParameteriv),
+ MethodDef( GetTexParameterfv),
+ MethodDef( GetTexParameteriv),
+ MethodDef( Hint),
+ MethodDef( IndexMask),
+ MethodDef( Indexd),
+ MethodDef( Indexdv),
+ MethodDef( Indexf),
+ MethodDef( Indexfv),
+ MethodDef( Indexi),
+ MethodDef( Indexiv),
+ MethodDef( Indexs),
+ MethodDef( Indexsv),
+ MethodDef( InitNames),
+ MethodDef( IsEnabled),
+ MethodDef( IsList),
+ MethodDef( IsTexture),
+ MethodDef( LightModelf),
+ MethodDef( LightModelfv),
+ MethodDef( LightModeli),
+ MethodDef( LightModeliv),
+ MethodDef( Lightf),
+ MethodDef( Lightfv),
+ MethodDef( Lighti),
+ MethodDef( Lightiv),
+ MethodDef( LineStipple),
+ MethodDef( LineWidth),
+ MethodDef( ListBase),
+ MethodDef( LoadIdentity),
+ MethodDef( LoadMatrixd),
+ MethodDef( LoadMatrixf),
+ MethodDef( LoadName),
+ MethodDef( LogicOp),
+ MethodDef( Map1d),
+ MethodDef( Map1f),
+ MethodDef( Map2d),
+ MethodDef( Map2f),
+ MethodDef( MapGrid1d),
+ MethodDef( MapGrid1f),
+ MethodDef( MapGrid2d),
+ MethodDef( MapGrid2f),
+ MethodDef( Materialf),
+ MethodDef( Materialfv),
+ MethodDef( Materiali),
+ MethodDef( Materialiv),
+ MethodDef( MatrixMode),
+ MethodDef( MultMatrixd),
+ MethodDef( MultMatrixf),
+ MethodDef( NewList),
+ MethodDef( Normal3b),
+ MethodDef( Normal3bv),
+ MethodDef( Normal3d),
+ MethodDef( Normal3dv),
+ MethodDef( Normal3f),
+ MethodDef( Normal3fv),
+ MethodDef( Normal3i),
+ MethodDef( Normal3iv),
+ MethodDef( Normal3s),
+ MethodDef( Normal3sv),
+ MethodDef( Ortho),
+ MethodDef( PassThrough),
+ MethodDef( PixelMapfv),
+ MethodDef( PixelMapuiv),
+ MethodDef( PixelMapusv),
+ MethodDef( PixelStoref),
+ MethodDef( PixelStorei),
+ MethodDef( PixelTransferf),
+ MethodDef( PixelTransferi),
+ MethodDef( PixelZoom),
+ MethodDef( PointSize),
+ MethodDef( PolygonMode),
+ MethodDef( PolygonOffset),
+ MethodDef( PolygonStipple),
+ MethodDef( PopAttrib),
+ MethodDef( PopMatrix),
+ MethodDef( PopName),
+ MethodDef( PrioritizeTextures),
+ MethodDef( PushAttrib),
+ MethodDef( PushMatrix),
+ MethodDef( PushName),
+ MethodDef( RasterPos2d),
+ MethodDef( RasterPos2dv),
+ MethodDef( RasterPos2f),
+ MethodDef( RasterPos2fv),
+ MethodDef( RasterPos2i),
+ MethodDef( RasterPos2iv),
+ MethodDef( RasterPos2s),
+ MethodDef( RasterPos2sv),
+ MethodDef( RasterPos3d),
+ MethodDef( RasterPos3dv),
+ MethodDef( RasterPos3f),
+ MethodDef( RasterPos3fv),
+ MethodDef( RasterPos3i),
+ MethodDef( RasterPos3iv),
+ MethodDef( RasterPos3s),
+ MethodDef( RasterPos3sv),
+ MethodDef( RasterPos4d),
+ MethodDef( RasterPos4dv),
+ MethodDef( RasterPos4f),
+ MethodDef( RasterPos4fv),
+ MethodDef( RasterPos4i),
+ MethodDef( RasterPos4iv),
+ MethodDef( RasterPos4s),
+ MethodDef( RasterPos4sv),
+ MethodDef( ReadBuffer),
+ MethodDef( ReadPixels),
+ MethodDef( Rectd),
+ MethodDef( Rectdv),
+ MethodDef( Rectf),
+ MethodDef( Rectfv),
+ MethodDef( Recti),
+ MethodDef( Rectiv),
+ MethodDef( Rects),
+ MethodDef( Rectsv),
+ MethodDef( RenderMode),
+ MethodDef( Rotated),
+ MethodDef( Rotatef),
+ MethodDef( Scaled),
+ MethodDef( Scalef),
+ MethodDef( Scissor),
+ MethodDef( SelectBuffer),
+ MethodDef( ShadeModel),
+ MethodDef( StencilFunc),
+ MethodDef( StencilMask),
+ MethodDef( StencilOp),
+ MethodDef( TexCoord1d),
+ MethodDef( TexCoord1dv),
+ MethodDef( TexCoord1f),
+ MethodDef( TexCoord1fv),
+ MethodDef( TexCoord1i),
+ MethodDef( TexCoord1iv),
+ MethodDef( TexCoord1s),
+ MethodDef( TexCoord1sv),
+ MethodDef( TexCoord2d),
+ MethodDef( TexCoord2dv),
+ MethodDef( TexCoord2f),
+ MethodDef( TexCoord2fv),
+ MethodDef( TexCoord2i),
+ MethodDef( TexCoord2iv),
+ MethodDef( TexCoord2s),
+ MethodDef( TexCoord2sv),
+ MethodDef( TexCoord3d),
+ MethodDef( TexCoord3dv),
+ MethodDef( TexCoord3f),
+ MethodDef( TexCoord3fv),
+ MethodDef( TexCoord3i),
+ MethodDef( TexCoord3iv),
+ MethodDef( TexCoord3s),
+ MethodDef( TexCoord3sv),
+ MethodDef( TexCoord4d),
+ MethodDef( TexCoord4dv),
+ MethodDef( TexCoord4f),
+ MethodDef( TexCoord4fv),
+ MethodDef( TexCoord4i),
+ MethodDef( TexCoord4iv),
+ MethodDef( TexCoord4s),
+ MethodDef( TexCoord4sv),
+ MethodDef( TexEnvf),
+ MethodDef( TexEnvfv),
+ MethodDef( TexEnvi),
+ MethodDef( TexEnviv),
+ MethodDef( TexGend),
+ MethodDef( TexGendv),
+ MethodDef( TexGenf),
+ MethodDef( TexGenfv),
+ MethodDef( TexGeni),
+ MethodDef( TexGeniv),
+ MethodDef( TexImage1D),
+ MethodDef( TexImage2D),
+ MethodDef( TexParameterf),
+ MethodDef( TexParameterfv),
+ MethodDef( TexParameteri),
+ MethodDef( TexParameteriv),
+ MethodDef( Translated),
+ MethodDef( Translatef),
+ MethodDef( Vertex2d),
+ MethodDef( Vertex2dv),
+ MethodDef( Vertex2f),
+ MethodDef( Vertex2fv),
+ MethodDef( Vertex2i),
+ MethodDef( Vertex2iv),
+ MethodDef( Vertex2s),
+ MethodDef( Vertex2sv),
+ MethodDef( Vertex3d),
+ MethodDef( Vertex3dv),
+ MethodDef( Vertex3f),
+ MethodDef( Vertex3fv),
+ MethodDef( Vertex3i),
+ MethodDef( Vertex3iv),
+ MethodDef( Vertex3s),
+ MethodDef( Vertex3sv),
+ MethodDef( Vertex4d),
+ MethodDef( Vertex4dv),
+ MethodDef( Vertex4f),
+ MethodDef( Vertex4fv),
+ MethodDef( Vertex4i),
+ MethodDef( Vertex4iv),
+ MethodDef( Vertex4s),
+ MethodDef( Vertex4sv),
+ MethodDef( Viewport),
+#endif
+
+ {NULL, NULL}
+};
+
+PyObject *init_py_bgl(void)
+{
+ PyObject *mod= Py_InitModule(SUBMODULE(BGL), BGL_methods);
+ PyObject *dict= PyModule_GetDict(mod);
+
+ Buffer_Type.ob_type= &PyType_Type;
+
+ BPY_ADDCONST(dict, GL_CURRENT_BIT);
+ BPY_ADDCONST(dict, GL_POINT_BIT);
+ BPY_ADDCONST(dict, GL_LINE_BIT);
+ BPY_ADDCONST(dict, GL_POLYGON_BIT);
+ BPY_ADDCONST(dict, GL_POLYGON_STIPPLE_BIT);
+ BPY_ADDCONST(dict, GL_PIXEL_MODE_BIT);
+ BPY_ADDCONST(dict, GL_LIGHTING_BIT);
+ BPY_ADDCONST(dict, GL_FOG_BIT);
+ BPY_ADDCONST(dict, GL_DEPTH_BUFFER_BIT);
+ BPY_ADDCONST(dict, GL_ACCUM_BUFFER_BIT);
+ BPY_ADDCONST(dict, GL_STENCIL_BUFFER_BIT);
+ BPY_ADDCONST(dict, GL_VIEWPORT_BIT);
+ BPY_ADDCONST(dict, GL_TRANSFORM_BIT);
+ BPY_ADDCONST(dict, GL_ENABLE_BIT);
+ BPY_ADDCONST(dict, GL_COLOR_BUFFER_BIT);
+ BPY_ADDCONST(dict, GL_HINT_BIT);
+ BPY_ADDCONST(dict, GL_EVAL_BIT);
+ BPY_ADDCONST(dict, GL_LIST_BIT);
+ BPY_ADDCONST(dict, GL_TEXTURE_BIT);
+ BPY_ADDCONST(dict, GL_SCISSOR_BIT);
+ BPY_ADDCONST(dict, GL_ALL_ATTRIB_BITS);
+
+ BPY_ADDCONST(dict, GL_FALSE);
+ BPY_ADDCONST(dict, GL_TRUE);
+
+ BPY_ADDCONST(dict, GL_POINTS);
+ BPY_ADDCONST(dict, GL_LINES);
+ BPY_ADDCONST(dict, GL_LINE_LOOP);
+ BPY_ADDCONST(dict, GL_LINE_STRIP);
+ BPY_ADDCONST(dict, GL_TRIANGLES);
+ BPY_ADDCONST(dict, GL_TRIANGLE_STRIP);
+ BPY_ADDCONST(dict, GL_TRIANGLE_FAN);
+ BPY_ADDCONST(dict, GL_QUADS);
+ BPY_ADDCONST(dict, GL_QUAD_STRIP);
+ BPY_ADDCONST(dict, GL_POLYGON);
+
+ BPY_ADDCONST(dict, GL_ACCUM);
+ BPY_ADDCONST(dict, GL_LOAD);
+ BPY_ADDCONST(dict, GL_RETURN);
+ BPY_ADDCONST(dict, GL_MULT);
+ BPY_ADDCONST(dict, GL_ADD);
+
+ BPY_ADDCONST(dict, GL_NEVER);
+ BPY_ADDCONST(dict, GL_LESS);
+ BPY_ADDCONST(dict, GL_EQUAL);
+ BPY_ADDCONST(dict, GL_LEQUAL);
+ BPY_ADDCONST(dict, GL_GREATER);
+ BPY_ADDCONST(dict, GL_NOTEQUAL);
+ BPY_ADDCONST(dict, GL_GEQUAL);
+ BPY_ADDCONST(dict, GL_ALWAYS);
+
+ BPY_ADDCONST(dict, GL_ZERO);
+ BPY_ADDCONST(dict, GL_ONE);
+ BPY_ADDCONST(dict, GL_SRC_COLOR);
+ BPY_ADDCONST(dict, GL_ONE_MINUS_SRC_COLOR);
+ BPY_ADDCONST(dict, GL_SRC_ALPHA);
+ BPY_ADDCONST(dict, GL_ONE_MINUS_SRC_ALPHA);
+ BPY_ADDCONST(dict, GL_DST_ALPHA);
+ BPY_ADDCONST(dict, GL_ONE_MINUS_DST_ALPHA);
+
+ BPY_ADDCONST(dict, GL_DST_COLOR);
+ BPY_ADDCONST(dict, GL_ONE_MINUS_DST_COLOR);
+ BPY_ADDCONST(dict, GL_SRC_ALPHA_SATURATE);
+
+ BPY_ADDCONST(dict, GL_NONE);
+ BPY_ADDCONST(dict, GL_FRONT_LEFT);
+ BPY_ADDCONST(dict, GL_FRONT_RIGHT);
+ BPY_ADDCONST(dict, GL_BACK_LEFT);
+ BPY_ADDCONST(dict, GL_BACK_RIGHT);
+ BPY_ADDCONST(dict, GL_FRONT);
+ BPY_ADDCONST(dict, GL_BACK);
+ BPY_ADDCONST(dict, GL_LEFT);
+ BPY_ADDCONST(dict, GL_RIGHT);
+ BPY_ADDCONST(dict, GL_FRONT_AND_BACK);
+ BPY_ADDCONST(dict, GL_AUX0);
+ BPY_ADDCONST(dict, GL_AUX1);
+ BPY_ADDCONST(dict, GL_AUX2);
+ BPY_ADDCONST(dict, GL_AUX3);
+
+ BPY_ADDCONST(dict, GL_NO_ERROR);
+ BPY_ADDCONST(dict, GL_INVALID_ENUM);
+ BPY_ADDCONST(dict, GL_INVALID_VALUE);
+ BPY_ADDCONST(dict, GL_INVALID_OPERATION);
+ BPY_ADDCONST(dict, GL_STACK_OVERFLOW);
+ BPY_ADDCONST(dict, GL_STACK_UNDERFLOW);
+ BPY_ADDCONST(dict, GL_OUT_OF_MEMORY);
+
+ BPY_ADDCONST(dict, GL_2D);
+ BPY_ADDCONST(dict, GL_3D);
+ BPY_ADDCONST(dict, GL_3D_COLOR);
+ BPY_ADDCONST(dict, GL_3D_COLOR_TEXTURE);
+ BPY_ADDCONST(dict, GL_4D_COLOR_TEXTURE);
+
+ BPY_ADDCONST(dict, GL_PASS_THROUGH_TOKEN);
+ BPY_ADDCONST(dict, GL_POINT_TOKEN);
+ BPY_ADDCONST(dict, GL_LINE_TOKEN);
+ BPY_ADDCONST(dict, GL_POLYGON_TOKEN);
+ BPY_ADDCONST(dict, GL_BITMAP_TOKEN);
+ BPY_ADDCONST(dict, GL_DRAW_PIXEL_TOKEN);
+ BPY_ADDCONST(dict, GL_COPY_PIXEL_TOKEN);
+ BPY_ADDCONST(dict, GL_LINE_RESET_TOKEN);
+
+ BPY_ADDCONST(dict, GL_EXP);
+ BPY_ADDCONST(dict, GL_EXP2);
+
+ BPY_ADDCONST(dict, GL_CW);
+ BPY_ADDCONST(dict, GL_CCW);
+
+ BPY_ADDCONST(dict, GL_COEFF);
+ BPY_ADDCONST(dict, GL_ORDER);
+ BPY_ADDCONST(dict, GL_DOMAIN);
+
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_I_TO_I);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_S_TO_S);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_I_TO_R);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_I_TO_G);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_I_TO_B);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_I_TO_A);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_R_TO_R);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_G_TO_G);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_B_TO_B);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_A_TO_A);
+
+ BPY_ADDCONST(dict, GL_CURRENT_COLOR);
+ BPY_ADDCONST(dict, GL_CURRENT_INDEX);
+ BPY_ADDCONST(dict, GL_CURRENT_NORMAL);
+ BPY_ADDCONST(dict, GL_CURRENT_TEXTURE_COORDS);
+ BPY_ADDCONST(dict, GL_CURRENT_RASTER_COLOR);
+ BPY_ADDCONST(dict, GL_CURRENT_RASTER_INDEX);
+ BPY_ADDCONST(dict, GL_CURRENT_RASTER_TEXTURE_COORDS);
+ BPY_ADDCONST(dict, GL_CURRENT_RASTER_POSITION);
+ BPY_ADDCONST(dict, GL_CURRENT_RASTER_POSITION_VALID);
+ BPY_ADDCONST(dict, GL_CURRENT_RASTER_DISTANCE);
+ BPY_ADDCONST(dict, GL_POINT_SMOOTH);
+ BPY_ADDCONST(dict, GL_POINT_SIZE);
+ BPY_ADDCONST(dict, GL_POINT_SIZE_RANGE);
+ BPY_ADDCONST(dict, GL_POINT_SIZE_GRANULARITY);
+ BPY_ADDCONST(dict, GL_LINE_SMOOTH);
+ BPY_ADDCONST(dict, GL_LINE_WIDTH);
+ BPY_ADDCONST(dict, GL_LINE_WIDTH_RANGE);
+ BPY_ADDCONST(dict, GL_LINE_WIDTH_GRANULARITY);
+ BPY_ADDCONST(dict, GL_LINE_STIPPLE);
+ BPY_ADDCONST(dict, GL_LINE_STIPPLE_PATTERN);
+ BPY_ADDCONST(dict, GL_LINE_STIPPLE_REPEAT);
+ BPY_ADDCONST(dict, GL_LIST_MODE);
+ BPY_ADDCONST(dict, GL_MAX_LIST_NESTING);
+ BPY_ADDCONST(dict, GL_LIST_BASE);
+ BPY_ADDCONST(dict, GL_LIST_INDEX);
+ BPY_ADDCONST(dict, GL_POLYGON_MODE);
+ BPY_ADDCONST(dict, GL_POLYGON_SMOOTH);
+ BPY_ADDCONST(dict, GL_POLYGON_STIPPLE);
+ BPY_ADDCONST(dict, GL_EDGE_FLAG);
+ BPY_ADDCONST(dict, GL_CULL_FACE);
+ BPY_ADDCONST(dict, GL_CULL_FACE_MODE);
+ BPY_ADDCONST(dict, GL_FRONT_FACE);
+ BPY_ADDCONST(dict, GL_LIGHTING);
+ BPY_ADDCONST(dict, GL_LIGHT_MODEL_LOCAL_VIEWER);
+ BPY_ADDCONST(dict, GL_LIGHT_MODEL_TWO_SIDE);
+ BPY_ADDCONST(dict, GL_LIGHT_MODEL_AMBIENT);
+ BPY_ADDCONST(dict, GL_SHADE_MODEL);
+ BPY_ADDCONST(dict, GL_COLOR_MATERIAL_FACE);
+ BPY_ADDCONST(dict, GL_COLOR_MATERIAL_PARAMETER);
+ BPY_ADDCONST(dict, GL_COLOR_MATERIAL);
+ BPY_ADDCONST(dict, GL_FOG);
+ BPY_ADDCONST(dict, GL_FOG_INDEX);
+ BPY_ADDCONST(dict, GL_FOG_DENSITY);
+ BPY_ADDCONST(dict, GL_FOG_START);
+ BPY_ADDCONST(dict, GL_FOG_END);
+ BPY_ADDCONST(dict, GL_FOG_MODE);
+ BPY_ADDCONST(dict, GL_FOG_COLOR);
+ BPY_ADDCONST(dict, GL_DEPTH_RANGE);
+ BPY_ADDCONST(dict, GL_DEPTH_TEST);
+ BPY_ADDCONST(dict, GL_DEPTH_WRITEMASK);
+ BPY_ADDCONST(dict, GL_DEPTH_CLEAR_VALUE);
+ BPY_ADDCONST(dict, GL_DEPTH_FUNC);
+ BPY_ADDCONST(dict, GL_ACCUM_CLEAR_VALUE);
+ BPY_ADDCONST(dict, GL_STENCIL_TEST);
+ BPY_ADDCONST(dict, GL_STENCIL_CLEAR_VALUE);
+ BPY_ADDCONST(dict, GL_STENCIL_FUNC);
+ BPY_ADDCONST(dict, GL_STENCIL_VALUE_MASK);
+ BPY_ADDCONST(dict, GL_STENCIL_FAIL);
+ BPY_ADDCONST(dict, GL_STENCIL_PASS_DEPTH_FAIL);
+ BPY_ADDCONST(dict, GL_STENCIL_PASS_DEPTH_PASS);
+ BPY_ADDCONST(dict, GL_STENCIL_REF);
+ BPY_ADDCONST(dict, GL_STENCIL_WRITEMASK);
+ BPY_ADDCONST(dict, GL_MATRIX_MODE);
+ BPY_ADDCONST(dict, GL_NORMALIZE);
+ BPY_ADDCONST(dict, GL_VIEWPORT);
+ BPY_ADDCONST(dict, GL_MODELVIEW_STACK_DEPTH);
+ BPY_ADDCONST(dict, GL_PROJECTION_STACK_DEPTH);
+ BPY_ADDCONST(dict, GL_TEXTURE_STACK_DEPTH);
+ BPY_ADDCONST(dict, GL_MODELVIEW_MATRIX);
+ BPY_ADDCONST(dict, GL_PROJECTION_MATRIX);
+ BPY_ADDCONST(dict, GL_TEXTURE_MATRIX);
+ BPY_ADDCONST(dict, GL_ATTRIB_STACK_DEPTH);
+ BPY_ADDCONST(dict, GL_ALPHA_TEST);
+ BPY_ADDCONST(dict, GL_ALPHA_TEST_FUNC);
+ BPY_ADDCONST(dict, GL_ALPHA_TEST_REF);
+ BPY_ADDCONST(dict, GL_DITHER);
+ BPY_ADDCONST(dict, GL_BLEND_DST);
+ BPY_ADDCONST(dict, GL_BLEND_SRC);
+ BPY_ADDCONST(dict, GL_BLEND);
+ BPY_ADDCONST(dict, GL_LOGIC_OP_MODE);
+ BPY_ADDCONST(dict, GL_LOGIC_OP);
+ BPY_ADDCONST(dict, GL_AUX_BUFFERS);
+ BPY_ADDCONST(dict, GL_DRAW_BUFFER);
+ BPY_ADDCONST(dict, GL_READ_BUFFER);
+ BPY_ADDCONST(dict, GL_SCISSOR_BOX);
+ BPY_ADDCONST(dict, GL_SCISSOR_TEST);
+ BPY_ADDCONST(dict, GL_INDEX_CLEAR_VALUE);
+ BPY_ADDCONST(dict, GL_INDEX_WRITEMASK);
+ BPY_ADDCONST(dict, GL_COLOR_CLEAR_VALUE);
+ BPY_ADDCONST(dict, GL_COLOR_WRITEMASK);
+ BPY_ADDCONST(dict, GL_INDEX_MODE);
+ BPY_ADDCONST(dict, GL_RGBA_MODE);
+ BPY_ADDCONST(dict, GL_DOUBLEBUFFER);
+ BPY_ADDCONST(dict, GL_STEREO);
+ BPY_ADDCONST(dict, GL_RENDER_MODE);
+ BPY_ADDCONST(dict, GL_PERSPECTIVE_CORRECTION_HINT);
+ BPY_ADDCONST(dict, GL_POINT_SMOOTH_HINT);
+ BPY_ADDCONST(dict, GL_LINE_SMOOTH_HINT);
+ BPY_ADDCONST(dict, GL_POLYGON_SMOOTH_HINT);
+ BPY_ADDCONST(dict, GL_FOG_HINT);
+ BPY_ADDCONST(dict, GL_TEXTURE_GEN_S);
+ BPY_ADDCONST(dict, GL_TEXTURE_GEN_T);
+ BPY_ADDCONST(dict, GL_TEXTURE_GEN_R);
+ BPY_ADDCONST(dict, GL_TEXTURE_GEN_Q);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_I_TO_I_SIZE);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_S_TO_S_SIZE);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_I_TO_R_SIZE);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_I_TO_G_SIZE);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_I_TO_B_SIZE);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_I_TO_A_SIZE);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_R_TO_R_SIZE);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_G_TO_G_SIZE);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_B_TO_B_SIZE);
+ BPY_ADDCONST(dict, GL_PIXEL_MAP_A_TO_A_SIZE);
+ BPY_ADDCONST(dict, GL_UNPACK_SWAP_BYTES);
+ BPY_ADDCONST(dict, GL_UNPACK_LSB_FIRST);
+ BPY_ADDCONST(dict, GL_UNPACK_ROW_LENGTH);
+ BPY_ADDCONST(dict, GL_UNPACK_SKIP_ROWS);
+ BPY_ADDCONST(dict, GL_UNPACK_SKIP_PIXELS);
+ BPY_ADDCONST(dict, GL_UNPACK_ALIGNMENT);
+ BPY_ADDCONST(dict, GL_PACK_SWAP_BYTES);
+ BPY_ADDCONST(dict, GL_PACK_LSB_FIRST);
+ BPY_ADDCONST(dict, GL_PACK_ROW_LENGTH);
+ BPY_ADDCONST(dict, GL_PACK_SKIP_ROWS);
+ BPY_ADDCONST(dict, GL_PACK_SKIP_PIXELS);
+ BPY_ADDCONST(dict, GL_PACK_ALIGNMENT);
+ BPY_ADDCONST(dict, GL_MAP_COLOR);
+ BPY_ADDCONST(dict, GL_MAP_STENCIL);
+ BPY_ADDCONST(dict, GL_INDEX_SHIFT);
+ BPY_ADDCONST(dict, GL_INDEX_OFFSET);
+ BPY_ADDCONST(dict, GL_RED_SCALE);
+ BPY_ADDCONST(dict, GL_RED_BIAS);
+ BPY_ADDCONST(dict, GL_ZOOM_X);
+ BPY_ADDCONST(dict, GL_ZOOM_Y);
+ BPY_ADDCONST(dict, GL_GREEN_SCALE);
+ BPY_ADDCONST(dict, GL_GREEN_BIAS);
+ BPY_ADDCONST(dict, GL_BLUE_SCALE);
+ BPY_ADDCONST(dict, GL_BLUE_BIAS);
+ BPY_ADDCONST(dict, GL_ALPHA_SCALE);
+ BPY_ADDCONST(dict, GL_ALPHA_BIAS);
+ BPY_ADDCONST(dict, GL_DEPTH_SCALE);
+ BPY_ADDCONST(dict, GL_DEPTH_BIAS);
+ BPY_ADDCONST(dict, GL_MAX_EVAL_ORDER);
+ BPY_ADDCONST(dict, GL_MAX_LIGHTS);
+ BPY_ADDCONST(dict, GL_MAX_CLIP_PLANES);
+ BPY_ADDCONST(dict, GL_MAX_TEXTURE_SIZE);
+ BPY_ADDCONST(dict, GL_MAX_PIXEL_MAP_TABLE);
+ BPY_ADDCONST(dict, GL_MAX_ATTRIB_STACK_DEPTH);
+ BPY_ADDCONST(dict, GL_MAX_MODELVIEW_STACK_DEPTH);
+ BPY_ADDCONST(dict, GL_MAX_NAME_STACK_DEPTH);
+ BPY_ADDCONST(dict, GL_MAX_PROJECTION_STACK_DEPTH);
+ BPY_ADDCONST(dict, GL_MAX_TEXTURE_STACK_DEPTH);
+ BPY_ADDCONST(dict, GL_MAX_VIEWPORT_DIMS);
+ BPY_ADDCONST(dict, GL_SUBPIXEL_BITS);
+ BPY_ADDCONST(dict, GL_INDEX_BITS);
+ BPY_ADDCONST(dict, GL_RED_BITS);
+ BPY_ADDCONST(dict, GL_GREEN_BITS);
+ BPY_ADDCONST(dict, GL_BLUE_BITS);
+ BPY_ADDCONST(dict, GL_ALPHA_BITS);
+ BPY_ADDCONST(dict, GL_DEPTH_BITS);
+ BPY_ADDCONST(dict, GL_STENCIL_BITS);
+ BPY_ADDCONST(dict, GL_ACCUM_RED_BITS);
+ BPY_ADDCONST(dict, GL_ACCUM_GREEN_BITS);
+ BPY_ADDCONST(dict, GL_ACCUM_BLUE_BITS);
+ BPY_ADDCONST(dict, GL_ACCUM_ALPHA_BITS);
+ BPY_ADDCONST(dict, GL_NAME_STACK_DEPTH);
+ BPY_ADDCONST(dict, GL_AUTO_NORMAL);
+ BPY_ADDCONST(dict, GL_MAP1_COLOR_4);
+ BPY_ADDCONST(dict, GL_MAP1_INDEX);
+ BPY_ADDCONST(dict, GL_MAP1_NORMAL);
+ BPY_ADDCONST(dict, GL_MAP1_TEXTURE_COORD_1);
+ BPY_ADDCONST(dict, GL_MAP1_TEXTURE_COORD_2);
+ BPY_ADDCONST(dict, GL_MAP1_TEXTURE_COORD_3);
+ BPY_ADDCONST(dict, GL_MAP1_TEXTURE_COORD_4);
+ BPY_ADDCONST(dict, GL_MAP1_VERTEX_3);
+ BPY_ADDCONST(dict, GL_MAP1_VERTEX_4);
+ BPY_ADDCONST(dict, GL_MAP2_COLOR_4);
+ BPY_ADDCONST(dict, GL_MAP2_INDEX);
+ BPY_ADDCONST(dict, GL_MAP2_NORMAL);
+ BPY_ADDCONST(dict, GL_MAP2_TEXTURE_COORD_1);
+ BPY_ADDCONST(dict, GL_MAP2_TEXTURE_COORD_2);
+ BPY_ADDCONST(dict, GL_MAP2_TEXTURE_COORD_3);
+ BPY_ADDCONST(dict, GL_MAP2_TEXTURE_COORD_4);
+ BPY_ADDCONST(dict, GL_MAP2_VERTEX_3);
+ BPY_ADDCONST(dict, GL_MAP2_VERTEX_4);
+ BPY_ADDCONST(dict, GL_MAP1_GRID_DOMAIN);
+ BPY_ADDCONST(dict, GL_MAP1_GRID_SEGMENTS);
+ BPY_ADDCONST(dict, GL_MAP2_GRID_DOMAIN);
+ BPY_ADDCONST(dict, GL_MAP2_GRID_SEGMENTS);
+ BPY_ADDCONST(dict, GL_TEXTURE_1D);
+ BPY_ADDCONST(dict, GL_TEXTURE_2D);
+
+ BPY_ADDCONST(dict, GL_TEXTURE_WIDTH);
+ BPY_ADDCONST(dict, GL_TEXTURE_HEIGHT);
+ BPY_ADDCONST(dict, GL_TEXTURE_COMPONENTS);
+ BPY_ADDCONST(dict, GL_TEXTURE_BORDER_COLOR);
+ BPY_ADDCONST(dict, GL_TEXTURE_BORDER);
+
+ BPY_ADDCONST(dict, GL_DONT_CARE);
+ BPY_ADDCONST(dict, GL_FASTEST);
+ BPY_ADDCONST(dict, GL_NICEST);
+
+ BPY_ADDCONST(dict, GL_AMBIENT);
+ BPY_ADDCONST(dict, GL_DIFFUSE);
+ BPY_ADDCONST(dict, GL_SPECULAR);
+ BPY_ADDCONST(dict, GL_POSITION);
+ BPY_ADDCONST(dict, GL_SPOT_DIRECTION);
+ BPY_ADDCONST(dict, GL_SPOT_EXPONENT);
+ BPY_ADDCONST(dict, GL_SPOT_CUTOFF);
+ BPY_ADDCONST(dict, GL_CONSTANT_ATTENUATION);
+ BPY_ADDCONST(dict, GL_LINEAR_ATTENUATION);
+ BPY_ADDCONST(dict, GL_QUADRATIC_ATTENUATION);
+
+ BPY_ADDCONST(dict, GL_COMPILE);
+ BPY_ADDCONST(dict, GL_COMPILE_AND_EXECUTE);
+
+ BPY_ADDCONST(dict, GL_BYTE);
+ BPY_ADDCONST(dict, GL_UNSIGNED_BYTE);
+ BPY_ADDCONST(dict, GL_SHORT);
+ BPY_ADDCONST(dict, GL_UNSIGNED_SHORT);
+ BPY_ADDCONST(dict, GL_INT);
+ BPY_ADDCONST(dict, GL_UNSIGNED_INT);
+ BPY_ADDCONST(dict, GL_FLOAT);
+ BPY_ADDCONST(dict, GL_2_BYTES);
+ BPY_ADDCONST(dict, GL_3_BYTES);
+ BPY_ADDCONST(dict, GL_4_BYTES);
+
+ BPY_ADDCONST(dict, GL_CLEAR);
+ BPY_ADDCONST(dict, GL_AND);
+ BPY_ADDCONST(dict, GL_AND_REVERSE);
+ BPY_ADDCONST(dict, GL_COPY);
+ BPY_ADDCONST(dict, GL_AND_INVERTED);
+ BPY_ADDCONST(dict, GL_NOOP);
+ BPY_ADDCONST(dict, GL_XOR);
+ BPY_ADDCONST(dict, GL_OR);
+ BPY_ADDCONST(dict, GL_NOR);
+ BPY_ADDCONST(dict, GL_EQUIV);
+ BPY_ADDCONST(dict, GL_INVERT);
+ BPY_ADDCONST(dict, GL_OR_REVERSE);
+ BPY_ADDCONST(dict, GL_COPY_INVERTED);
+ BPY_ADDCONST(dict, GL_OR_INVERTED);
+ BPY_ADDCONST(dict, GL_NAND);
+ BPY_ADDCONST(dict, GL_SET);
+
+ BPY_ADDCONST(dict, GL_EMISSION);
+ BPY_ADDCONST(dict, GL_SHININESS);
+ BPY_ADDCONST(dict, GL_AMBIENT_AND_DIFFUSE);
+ BPY_ADDCONST(dict, GL_COLOR_INDEXES);
+
+ BPY_ADDCONST(dict, GL_MODELVIEW);
+ BPY_ADDCONST(dict, GL_PROJECTION);
+ BPY_ADDCONST(dict, GL_TEXTURE);
+
+ BPY_ADDCONST(dict, GL_COLOR);
+ BPY_ADDCONST(dict, GL_DEPTH);
+ BPY_ADDCONST(dict, GL_STENCIL);
+
+ BPY_ADDCONST(dict, GL_COLOR_INDEX);
+ BPY_ADDCONST(dict, GL_STENCIL_INDEX);
+ BPY_ADDCONST(dict, GL_DEPTH_COMPONENT);
+ BPY_ADDCONST(dict, GL_RED);
+ BPY_ADDCONST(dict, GL_GREEN);
+ BPY_ADDCONST(dict, GL_BLUE);
+ BPY_ADDCONST(dict, GL_ALPHA);
+ BPY_ADDCONST(dict, GL_RGB);
+ BPY_ADDCONST(dict, GL_RGBA);
+ BPY_ADDCONST(dict, GL_LUMINANCE);
+ BPY_ADDCONST(dict, GL_LUMINANCE_ALPHA);
+
+ BPY_ADDCONST(dict, GL_BITMAP);
+
+ BPY_ADDCONST(dict, GL_POINT);
+ BPY_ADDCONST(dict, GL_LINE);
+ BPY_ADDCONST(dict, GL_FILL);
+
+ BPY_ADDCONST(dict, GL_RENDER);
+ BPY_ADDCONST(dict, GL_FEEDBACK);
+ BPY_ADDCONST(dict, GL_SELECT);
+
+ BPY_ADDCONST(dict, GL_FLAT);
+ BPY_ADDCONST(dict, GL_SMOOTH);
+
+ BPY_ADDCONST(dict, GL_KEEP);
+ BPY_ADDCONST(dict, GL_REPLACE);
+ BPY_ADDCONST(dict, GL_INCR);
+ BPY_ADDCONST(dict, GL_DECR);
+
+ BPY_ADDCONST(dict, GL_VENDOR);
+ BPY_ADDCONST(dict, GL_RENDERER);
+ BPY_ADDCONST(dict, GL_VERSION);
+ BPY_ADDCONST(dict, GL_EXTENSIONS);
+
+ BPY_ADDCONST(dict, GL_S);
+ BPY_ADDCONST(dict, GL_T);
+ BPY_ADDCONST(dict, GL_R);
+ BPY_ADDCONST(dict, GL_Q);
+
+ BPY_ADDCONST(dict, GL_MODULATE);
+ BPY_ADDCONST(dict, GL_DECAL);
+
+ BPY_ADDCONST(dict, GL_TEXTURE_ENV_MODE);
+ BPY_ADDCONST(dict, GL_TEXTURE_ENV_COLOR);
+
+ BPY_ADDCONST(dict, GL_TEXTURE_ENV);
+
+ BPY_ADDCONST(dict, GL_EYE_LINEAR);
+ BPY_ADDCONST(dict, GL_OBJECT_LINEAR);
+ BPY_ADDCONST(dict, GL_SPHERE_MAP);
+
+ BPY_ADDCONST(dict, GL_TEXTURE_GEN_MODE);
+ BPY_ADDCONST(dict, GL_OBJECT_PLANE);
+ BPY_ADDCONST(dict, GL_EYE_PLANE);
+
+ BPY_ADDCONST(dict, GL_NEAREST);
+ BPY_ADDCONST(dict, GL_LINEAR);
+
+ BPY_ADDCONST(dict, GL_NEAREST_MIPMAP_NEAREST);
+ BPY_ADDCONST(dict, GL_LINEAR_MIPMAP_NEAREST);
+ BPY_ADDCONST(dict, GL_NEAREST_MIPMAP_LINEAR);
+ BPY_ADDCONST(dict, GL_LINEAR_MIPMAP_LINEAR);
+
+ BPY_ADDCONST(dict, GL_TEXTURE_MAG_FILTER);
+ BPY_ADDCONST(dict, GL_TEXTURE_MIN_FILTER);
+ BPY_ADDCONST(dict, GL_TEXTURE_WRAP_S);
+ BPY_ADDCONST(dict, GL_TEXTURE_WRAP_T);
+
+ BPY_ADDCONST(dict, GL_CLAMP);
+ BPY_ADDCONST(dict, GL_REPEAT);
+
+ BPY_ADDCONST(dict, GL_CLIP_PLANE0);
+ BPY_ADDCONST(dict, GL_CLIP_PLANE1);
+ BPY_ADDCONST(dict, GL_CLIP_PLANE2);
+ BPY_ADDCONST(dict, GL_CLIP_PLANE3);
+ BPY_ADDCONST(dict, GL_CLIP_PLANE4);
+ BPY_ADDCONST(dict, GL_CLIP_PLANE5);
+
+ BPY_ADDCONST(dict, GL_LIGHT0);
+ BPY_ADDCONST(dict, GL_LIGHT1);
+ BPY_ADDCONST(dict, GL_LIGHT2);
+ BPY_ADDCONST(dict, GL_LIGHT3);
+ BPY_ADDCONST(dict, GL_LIGHT4);
+ BPY_ADDCONST(dict, GL_LIGHT5);
+ BPY_ADDCONST(dict, GL_LIGHT6);
+ BPY_ADDCONST(dict, GL_LIGHT7);
+
+ BPY_ADDCONST(dict, GL_POLYGON_OFFSET_UNITS);
+ BPY_ADDCONST(dict, GL_POLYGON_OFFSET_POINT);
+ BPY_ADDCONST(dict, GL_POLYGON_OFFSET_LINE);
+ BPY_ADDCONST(dict, GL_POLYGON_OFFSET_FILL);
+ BPY_ADDCONST(dict, GL_POLYGON_OFFSET_FACTOR);
+
+ BPY_ADDCONST(dict, GL_TEXTURE_PRIORITY);
+ BPY_ADDCONST(dict, GL_TEXTURE_RESIDENT);
+ BPY_ADDCONST(dict, GL_TEXTURE_BINDING_1D);
+ BPY_ADDCONST(dict, GL_TEXTURE_BINDING_2D);
+
+ return mod;
+}
+
+void initDraw(void)
+{
+ init_py_draw();
+ init_py_bgl();
+}
diff --git a/source/blender/bpython/intern/opy_matrix.c b/source/blender/bpython/intern/opy_matrix.c
new file mode 100644
index 00000000000..cd93bd5f311
--- /dev/null
+++ b/source/blender/bpython/intern/opy_matrix.c
@@ -0,0 +1,173 @@
+/* python.c MIXED MODEL
+ *
+ * june 99
+ * $Id$
+ *
+ * this code might die...
+ *
+ * ***** 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_tools.h"
+#include "BPY_macros.h"
+
+#include "BLI_arithb.h"
+#include "opy_vector.h"
+
+PyObject *BPY_tuple_repr(PyObject *self, int size);
+
+/* PROTOS */
+// PyObject *newVectorObject(float *vec, int size);
+
+/*****************************/
+/* Matrix Python Object */
+/*****************************/
+
+
+#define GETROWVECTOR(mat, i) ( (float *) mat[i])
+
+static void Matrix_dealloc(MatrixObject *self) {
+ Py_DECREF(self->rows[0]);
+ Py_DECREF(self->rows[1]);
+ Py_DECREF(self->rows[2]);
+ Py_DECREF(self->rows[3]);
+
+ PyMem_DEL(self);
+}
+
+#undef MethodDef
+#define MethodDef(func) _MethodDef(func, Matrix)
+
+static char Matrix_inverse_doc[] = "() - returns inverse of matrix";
+
+static PyObject *Matrix_inverse(PyObject *self, PyObject *args)
+{
+ float inverse[4][4];
+ MatrixObject *mat = (MatrixObject *) self;
+ Mat4Invert(inverse, mat->mat);
+ return newMatrixObject(inverse);
+}
+
+struct PyMethodDef Matrix_methods[] = {
+ MethodDef(inverse),
+ {NULL, NULL}
+};
+
+static PyObject *Matrix_getattr(MatrixObject *self, char *name)
+{
+ PyObject *list;
+ float val[3];
+
+ if (strcmp(name, "rot")==0) {
+ float mat3[3][3];
+
+ Mat3CpyMat4(mat3, self->mat);
+ Mat3ToEul(mat3, val);
+
+ } else if (strcmp(name, "size")==0) {
+ Mat4ToSize(self->mat, val);
+ /* Oh man, this is BAD. */
+ } else if (strcmp(name, "loc")==0) {
+ VECCOPY(val, (float *) (self->mat)[3]);
+
+ } else {
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+ }
+
+ list= PyList_New(3);
+ PyList_SetItem(list, 0, PyFloat_FromDouble(val[0]));
+ PyList_SetItem(list, 1, PyFloat_FromDouble(val[1]));
+ PyList_SetItem(list, 2, PyFloat_FromDouble(val[2]));
+
+ return list;
+}
+
+static int Matrix_setattr(MatrixObject *self, char *name, PyObject *v) {
+ return -1;
+}
+
+static PyObject *Matrix_repr (MatrixObject *self) {
+ return BPY_tuple_repr((PyObject *) self, 4);
+}
+
+static PyObject *Matrix_item(MatrixObject *self, int i)
+{
+ if (i < 0 || i >= 4) {
+ PyErr_SetString(PyExc_IndexError, "array index out of range");
+ return NULL;
+ }
+ return BPY_incr_ret(self->rows[i]);
+}
+
+static PySequenceMethods Matrix_SeqMethods = {
+ (inquiry) 0, /*sq_length*/
+ (binaryfunc) 0, /*sq_concat*/
+ (intargfunc) 0, /*sq_repeat*/
+ (intargfunc) Matrix_item, /*sq_item*/
+ (intintargfunc) 0, /*sq_slice*/
+ (intobjargproc) 0, /*sq_ass_item*/
+ (intintobjargproc) 0, /*sq_ass_slice*/
+};
+
+PyTypeObject Matrix_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "Matrix", /*tp_name*/
+ sizeof(MatrixObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor) Matrix_dealloc, /*tp_dealloc*/
+ (printfunc) 0, /*tp_print*/
+ (getattrfunc) Matrix_getattr, /*tp_getattr*/
+ (setattrfunc) Matrix_setattr, /*tp_setattr*/
+ 0, /*tp_compare*/
+ (reprfunc) Matrix_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &Matrix_SeqMethods, /*tp_as_sequence*/
+};
+
+PyObject *newMatrixObject(Matrix4Ptr mat) {
+ MatrixObject *self;
+
+ self= PyObject_NEW(MatrixObject, &Matrix_Type);
+ self->mat= mat;
+
+ BPY_TRY(self->rows[0]= newVectorObject(GETROWVECTOR(self->mat, 0), 4));
+ BPY_TRY(self->rows[1]= newVectorObject(GETROWVECTOR(self->mat, 1), 4));
+ BPY_TRY(self->rows[2]= newVectorObject(GETROWVECTOR(self->mat, 2), 4));
+ BPY_TRY(self->rows[3]= newVectorObject(GETROWVECTOR(self->mat, 3), 4));
+
+ return (PyObject*) self;
+}
+
+void init_py_matrix(void) {
+ Matrix_Type.ob_type = &PyType_Type;
+}
diff --git a/source/blender/bpython/intern/opy_nmesh.c b/source/blender/bpython/intern/opy_nmesh.c
new file mode 100644
index 00000000000..48de7726dd8
--- /dev/null
+++ b/source/blender/bpython/intern/opy_nmesh.c
@@ -0,0 +1,1716 @@
+/* python.c MIXED MODEL
+ *
+ * june 99
+ * $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 "b_interface.h"
+#include "BPY_tools.h"
+#include "BPY_main.h"
+
+#include "opy_datablock.h"
+#include "opy_nmesh.h"
+
+#include "MEM_guardedalloc.h"
+#include "BIF_editmesh.h" /* vertexnormals_mesh() */
+#include "BDR_editface.h" /* make_tfaces */
+
+#include "BKE_mesh.h"
+#include "BKE_main.h"
+#include "BKE_global.h"
+#include "BKE_library.h"
+#include "BKE_displist.h"
+#include "BKE_screen.h"
+#include "BKE_object.h"
+#include "BPY_objtypes.h"
+#include "BLI_blenlib.h"
+#include "BIF_space.h"
+
+#include "opy_vector.h"
+
+#include "b_interface.h"
+/* PROTOS */
+
+static int convert_NMeshToMesh(Mesh *mesh, NMesh *nmesh);
+static int unlink_existingMeshdata(Mesh *mesh);
+void initNMesh(void);
+PyObject *init_py_nmesh(void);
+int BPY_check_sequence_consistency(PyObject *seq, PyTypeObject *against);
+
+/* TYPE OBJECTS */
+
+PyTypeObject NMesh_Type;
+PyTypeObject NMFace_Type;
+PyTypeObject NMVert_Type;
+PyTypeObject NMCol_Type;
+
+/* DEFINES */
+
+
+#define COL_R (b)
+#define COL_G (g)
+#define COL_B (r)
+#define COL_A (a)
+
+#define COLOR_CONVERT(col,comp) (col##->COL_##)
+
+/* GLOBALS */
+
+static PyObject *g_nmeshmodule = NULL;
+
+/*****************************/
+/* Mesh Color Object */
+/*****************************/
+
+static void NMCol_dealloc(PyObject *self) {
+ PyMem_DEL(self);
+}
+
+static NMCol *newcol (char r, char g, char b, char a) {
+ NMCol *mc= (NMCol *) PyObject_NEW(NMCol, &NMCol_Type);
+
+ mc->r= r;
+ mc->g= g;
+ mc->b= b;
+ mc->a= a;
+
+ return mc;
+}
+
+static char NMeshmodule_Col_doc[]=
+"([r, g, b, a]) - Get a new mesh color\n\
+\n\
+[r=255, g=255, b=255, a=255] Specify the color components";
+
+static PyObject *NMeshmodule_Col(PyObject *self, PyObject *args) {
+ int r=255, g=255, b=255, a=255;
+
+/*
+if(PyArg_ParseTuple(args, "fff|f", &fr, &fg, &fb, &fa))
+ return (PyObject *) newcol(255.0 * fr, 255.0 * fg, 255.0 * fb, 255.0 * fa);
+ */
+ if(PyArg_ParseTuple(args, "|iiii", &r, &g, &b, &a))
+ return (PyObject *) newcol(r, g, b, a);
+ return NULL;
+}
+
+static PyObject *NMCol_getattr(PyObject *self, char *name) {
+ NMCol *mc= (NMCol *) self;
+
+ if (strcmp(name, "r")==0) return Py_BuildValue("i", mc->r);
+ else if (strcmp(name, "g")==0) return Py_BuildValue("i", mc->g);
+ else if (strcmp(name, "b")==0) return Py_BuildValue("i", mc->b);
+ else if (strcmp(name, "a")==0) return Py_BuildValue("i", mc->a);
+
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+}
+
+static int NMCol_setattr(PyObject *self, char *name, PyObject *v) {
+ NMCol *mc= (NMCol *) self;
+ int ival;
+
+ if(!PyArg_Parse(v, "i", &ival)) return -1;
+
+ CLAMP(ival, 0, 255);
+
+ if (strcmp(name, "r")==0) mc->r= ival;
+ else if (strcmp(name, "g")==0) mc->g= ival;
+ else if (strcmp(name, "b")==0) mc->b= ival;
+ else if (strcmp(name, "a")==0) mc->a= ival;
+ else return -1;
+
+ return 0;
+}
+
+PyObject *NMCol_repr(NMCol *self)
+{
+ static char s[256];
+ sprintf (s, "[NMCol - <%d, %d, %d, %d>]", self->r, self->g, self->b, self->a);
+ return Py_BuildValue("s", s);
+}
+
+PyTypeObject NMCol_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "NMCol", /*tp_name*/
+ sizeof(NMCol), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor) NMCol_dealloc, /*tp_dealloc*/
+ (printfunc) 0, /*tp_print*/
+ (getattrfunc) NMCol_getattr, /*tp_getattr*/
+ (setattrfunc) NMCol_setattr, /*tp_setattr*/
+ 0, /*tp_compare*/
+ (reprfunc) NMCol_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+};
+
+
+/*****************************/
+/* NMesh Python Object */
+/*****************************/
+
+
+static void NMFace_dealloc(PyObject *self) {
+ NMFace *mf= (NMFace *) self;
+
+ Py_DECREF(mf->v);
+ Py_DECREF(mf->uv);
+ Py_DECREF(mf->col);
+
+ PyMem_DEL(self);
+
+}
+
+static NMFace *newNMFace(PyObject *vertexlist) {
+ NMFace *mf= PyObject_NEW(NMFace, &NMFace_Type);
+
+ mf->v= vertexlist;
+ mf->uv= PyList_New(0);
+ mf->tpage= NULL;
+ mf->mode = TF_DYNAMIC + TF_TEX;
+ mf->flag= TF_SELECT;
+ mf->transp= TF_SOLID;
+ mf->col= PyList_New(0);
+
+ mf->smooth= 0;
+ mf->mat_nr= 0;
+
+ return mf;
+}
+
+static char NMeshmodule_Face_doc[]=
+"(vertexlist = None) - Get a new face, and pass optional vertex list";
+static PyObject *NMeshmodule_Face(PyObject *self, PyObject *args) {
+ PyObject *vertlist = NULL;
+ BPY_TRY(PyArg_ParseTuple(args, "|O!", &PyList_Type, &vertlist));
+
+ if (!vertlist) {
+ vertlist = PyList_New(0);
+ }
+ return (PyObject *) newNMFace(vertlist);
+}
+
+/* XXX this code will be used later...
+static PyObject *Method_getmode(PyObject *self, PyObject *args) {
+ PyObject *dict, *list;
+ PyObject *constants, *values, *c;
+ int flag;
+ int i, n;
+
+ list = PyList_New(0);
+ dict = PyObject_GetAttrString(g_nmeshmodule, "Const");
+
+ if (!dict) return 0;
+
+ constants = PyDict_Keys(dict);
+ values = PyDict_Values(dict);
+
+ n = PySequence_Length(constants);
+ for (i = 0; i < n; i++)
+ {
+ flag = PyInt_AsLong(PySequence_GetItem(values, i));
+ if (flag & ((NMFace*) self)->mode)
+ {
+ c = PySequence_GetItem(constants, i);
+ PyList_Append(list, c)
+ }
+ }
+ return list;
+}
+*/
+
+static char NMFace_append_doc[]= "(vert) - appends Vertex 'vert' to face vertex list";
+
+static PyObject *NMFace_append(PyObject *self, PyObject *args)
+{
+ PyObject *vert;
+ NMFace *f= (NMFace *) self;
+
+ BPY_TRY(PyArg_ParseTuple(args, "O!", &NMVert_Type, &vert));
+ PyList_Append(f->v, vert);
+ RETURN_INC(Py_None);
+}
+
+
+#undef MethodDef
+#define MethodDef(func) {#func, NMFace_##func, METH_VARARGS, NMFace_##func##_doc}
+
+static struct PyMethodDef NMFace_methods[] = {
+ MethodDef(append),
+ {NULL, NULL}
+};
+
+static PyObject *NMFace_getattr(PyObject *self, char *name) {
+ NMFace *mf= (NMFace *) self;
+
+ if(strcmp(name, "v")==0)
+ return Py_BuildValue("O", mf->v);
+ else if (strcmp(name, "col")==0)
+ return Py_BuildValue("O", mf->col);
+ else if (strcmp(name, "mat")==0) // emulation XXX
+ return Py_BuildValue("i", mf->mat_nr);
+ else if (strcmp(name, "materialIndex")==0)
+ return Py_BuildValue("i", mf->mat_nr);
+ else if (strcmp(name, "smooth")==0)
+ return Py_BuildValue("i", mf->smooth);
+ else if (strcmp(name, "image")==0) {
+ if (mf->tpage)
+ return Py_BuildValue("O", (PyObject *) mf->tpage);
+ else
+ RETURN_INC(Py_None);
+ }
+ else if (strcmp(name, "mode")==0)
+ return Py_BuildValue("i", mf->mode);
+ else if (strcmp(name, "flag")==0)
+ return Py_BuildValue("i", mf->flag);
+ else if (strcmp(name, "transp")==0)
+ return Py_BuildValue("i", mf->transp);
+ else if (strcmp(name, "uv")==0)
+ return Py_BuildValue("O", mf->uv);
+
+ return Py_FindMethod(NMFace_methods, (PyObject*)self, name);
+/*
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+*/
+}
+
+static int NMFace_setattr(PyObject *self, char *name, PyObject *v) {
+ NMFace *mf= (NMFace *) self;
+ int ival;
+ PyObject *tmp;
+
+ if (STREQ(name, "v")) {
+ if(PySequence_Check(v)) {
+ Py_DECREF(mf->v);
+ mf->v= BPY_incr_ret(v);
+
+ return 0;
+ }
+ } else if (STREQ(name, "col")) {
+ if(PySequence_Check(v)) {
+ Py_DECREF(mf->col);
+ mf->col= BPY_incr_ret(v);
+
+ return 0;
+ }
+ } else if (STREQ(name, "mat") || STREQ(name, "materialIndex")) {
+ PyArg_Parse(v, "i", &ival);
+
+ mf->mat_nr= ival;
+
+ return 0;
+ } else if (STREQ(name, "smooth")) {
+ PyArg_Parse(v, "i", &ival);
+
+ mf->smooth= ival?1:0;
+
+ return 0;
+ } else if (STREQ(name, "uv")) {
+ if(PySequence_Check(v)) {
+ Py_DECREF(mf->uv);
+ mf->uv= BPY_incr_ret(v);
+ return 0;
+ }
+ } else if (STREQ(name, "flag")) {
+ PyArg_Parse(v, "i", &ival);
+ mf->flag = ival;
+ return 0;
+ } else if (STREQ(name, "mode")) {
+ PyArg_Parse(v, "i", &ival);
+ mf->mode = ival;
+ return 0;
+ } else if (STREQ(name, "transp")) {
+ PyArg_Parse(v, "i", &ival);
+ mf->transp = ival;
+ return 0;
+ } else if (STREQ(name, "image")) {
+ PyArg_Parse(v, "O", &tmp);
+ if (tmp == Py_None) {
+ mf->tpage = 0;
+ return 0;
+ }
+ if (!DataBlock_isType((DataBlock *) tmp, ID_IM))
+ {
+ PyErr_SetString(PyExc_TypeError, "expects Image Datablock type");
+ return -1;
+ }
+ mf->tpage = (DataBlock *) tmp;
+ return 0;
+ }
+
+ PyErr_SetString(PyExc_AttributeError, name);
+ return -1;
+}
+
+static PyObject *NMFace_repr (PyObject *self)
+{
+ return PyString_FromString("[NMFace]");
+}
+
+static int NMFace_len(NMFace *self)
+{
+ return PySequence_Length(self->v);
+}
+
+static PyObject *NMFace_item(NMFace *self, int i)
+{
+ return PySequence_GetItem(self->v, i); // new ref
+}
+
+static PyObject *NMFace_slice(NMFace *self, int begin, int end)
+{
+ return PyList_GetSlice(self->v, begin, end); // new ref
+}
+
+static PySequenceMethods NMFace_SeqMethods = {
+ (inquiry) NMFace_len, /* sq_length */
+ (binaryfunc) 0, /* sq_concat */
+ (intargfunc) 0, /* sq_repeat */
+ (intargfunc) NMFace_item, /* sq_item */
+ (intintargfunc) NMFace_slice, /* sq_slice */
+ (intobjargproc) 0, /* sq_ass_item */
+ (intintobjargproc) 0, /* sq_ass_slice */
+};
+
+
+PyTypeObject NMFace_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "NMFace", /*tp_name*/
+ sizeof(NMFace), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor) NMFace_dealloc, /*tp_dealloc*/
+ (printfunc) 0, /*tp_print*/
+ (getattrfunc) NMFace_getattr, /*tp_getattr*/
+ (setattrfunc) NMFace_setattr,/*tp_setattr*/
+ 0, /*tp_compare*/
+ (reprfunc) NMFace_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &NMFace_SeqMethods, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+};
+
+
+static NMVert *newvert(float *co) {
+ NMVert *mv= PyObject_NEW(NMVert, &NMVert_Type);
+
+ VECCOPY(mv->co, co);
+ mv->no[0]= mv->no[1]= mv->no[2]= 0.0;
+ mv->uvco[0]= mv->uvco[1]= mv->uvco[2]= 0.0;
+
+ return mv;
+}
+
+static char NMeshmodule_Vert_doc[]=
+"([x, y, z]) - Get a new vertice\n\
+\n\
+[x, y, z] Specify new coordinates";
+
+static PyObject *NMeshmodule_Vert(PyObject *self, PyObject *args) {
+ float co[3]= {0.0, 0.0, 0.0};
+
+ BPY_TRY(PyArg_ParseTuple(args, "|fff", &co[0], &co[1], &co[2]));
+
+ return (PyObject *) newvert(co);
+}
+
+static void NMVert_dealloc(PyObject *self) {
+ PyMem_DEL(self);
+}
+
+static PyObject *NMVert_getattr(PyObject *self, char *name) {
+ NMVert *mv= (NMVert *) self;
+
+ if (STREQ(name, "co") || STREQ(name, "loc")) return newVectorObject(mv->co, 3);
+ else if (STREQ(name, "no")) return newVectorObject(mv->no, 3);
+ else if (STREQ(name, "uvco")) return newVectorObject(mv->uvco, 3);
+ else if (STREQ(name, "index")) return PyInt_FromLong(mv->index);
+
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+}
+
+static int NMVert_setattr(PyObject *self, char *name, PyObject *v) {
+ NMVert *mv= (NMVert *) self;
+ int i;
+
+ if (STREQ(name,"index")) {
+ PyArg_Parse(v, "i", &i);
+ mv->index= i;
+ return 0;
+ } else if (STREQ(name, "uvco")) {
+ if (!PyArg_ParseTuple(v, "ff|f", &(mv->uvco[0]), &(mv->uvco[1]), &(mv->uvco[2]))) {
+ PyErr_SetString(PyExc_AttributeError, "Vector tuple or triple expected");
+ return -1;
+ }
+ return 0;
+/*
+PyErr_SetString(PyExc_AttributeError, "Use slice assignment: uvco[i]");
+ return -1;
+ */
+ }
+
+ PyErr_SetString(PyExc_AttributeError, name);
+ return -1;
+}
+
+
+static int NMVert_len(NMVert *self) {
+ return 3;
+}
+
+static PyObject *NMVert_item(NMVert *self, int i)
+{
+ if (i < 0 || i >= 3) {
+ PyErr_SetString(PyExc_IndexError, "array index out of range");
+ return NULL;
+ }
+ return Py_BuildValue("f", self->co[i]);
+}
+
+static PyObject *NMVert_slice(NMVert *self, int begin, int end)
+{
+ PyObject *list;
+ int count;
+
+ if (begin<0) begin= 0;
+ if (end>3) end= 3;
+ if (begin>end) begin= end;
+
+ list= PyList_New(end-begin);
+
+ for (count= begin; count<end; count++)
+ PyList_SetItem(list, count-begin, PyFloat_FromDouble(self->co[count]));
+
+ return list;
+}
+
+static int NMVert_ass_item(NMVert *self, int i, PyObject *ob)
+{
+ if (i < 0 || i >= 3) {
+ PyErr_SetString(PyExc_IndexError, "array assignment index out of range");
+ return -1;
+ }
+
+ if (!PyNumber_Check(ob)) {
+ PyErr_SetString(PyExc_IndexError, "NMVert member must be a number");
+ return -1;
+ }
+
+ self->co[i]= PyFloat_AsDouble(ob);
+/* if(!PyArg_Parse(ob, "f", &)) return -1; */
+
+ return 0;
+}
+
+/** I guess this hurts...
+ * sorry, couldn't resist (strubi) */
+
+static int NMVert_ass_slice(NMVert *self, int begin, int end, PyObject *seq)
+{
+ int count;
+
+ if (begin<0) begin= 0;
+ if (end>3) end= 3;
+ if (begin>end) begin= end;
+
+ if (!PySequence_Check(seq)) {
+ PyErr_SetString(PyExc_TypeError, "illegal argument type for built-in operation");
+ return -1;
+ }
+
+ if (PySequence_Length(seq)!=(end-begin)) {
+ PyErr_SetString(PyExc_TypeError, "size mismatch in slice assignment");
+ return -1;
+ }
+
+ for (count= begin; count<end; count++) {
+ PyObject *ob= PySequence_GetItem(seq, count);
+ if (!PyArg_Parse(ob, "f", &self->co[count])) {
+ Py_DECREF(ob);
+ return -1;
+ }
+ Py_DECREF(ob);
+ }
+
+ return 0;
+}
+
+static PySequenceMethods NMVert_SeqMethods = {
+ (inquiry) NMVert_len, /* sq_length */
+ (binaryfunc) 0, /* sq_concat */
+ (intargfunc) 0, /* sq_repeat */
+ (intargfunc) NMVert_item, /* sq_item */
+ (intintargfunc) NMVert_slice, /* sq_slice */
+ (intobjargproc) NMVert_ass_item, /* sq_ass_item */
+ (intintobjargproc) NMVert_ass_slice, /* sq_ass_slice */
+};
+
+PyTypeObject NMVert_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "NMVert", /*tp_name*/
+ sizeof(NMVert), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor) NMVert_dealloc, /*tp_dealloc*/
+ (printfunc) 0, /*tp_print*/
+ (getattrfunc) NMVert_getattr, /*tp_getattr*/
+ (setattrfunc) NMVert_setattr, /*tp_setattr*/
+ 0, /*tp_compare*/
+ (reprfunc) 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &NMVert_SeqMethods, /*tp_as_sequence*/
+};
+
+
+static void NMesh_dealloc(PyObject *self) {
+ NMesh *me= (NMesh *) self;
+
+ Py_DECREF(me->name);
+ Py_DECREF(me->verts);
+ Py_DECREF(me->faces);
+
+ PyMem_DEL(self);
+}
+
+
+static char NMesh_getSelectedFaces_doc[] = "(flag = None) - returns list of selected Faces\n\
+If flag = 1, return indices instead";
+static PyObject *NMesh_getSelectedFaces(PyObject *self, PyObject *args)
+{
+ NMesh *nm= (NMesh *) self;
+ Mesh *me = nm->mesh;
+ int flag = 0;
+
+ TFace *tf;
+ int i;
+ PyObject *l= PyList_New(0);
+
+ if (me == NULL) return NULL;
+
+ tf = me->tface;
+ if (tf == 0) {
+ return l;
+ }
+
+ if (!PyArg_ParseTuple(args, "|i", &flag))
+ return NULL;
+ if (flag) {
+ for (i =0 ; i < me->totface; i++) {
+ if (tf[i].flag & TF_SELECT ) {
+ PyList_Append(l, PyInt_FromLong(i));
+ }
+ }
+ } else {
+ for (i =0 ; i < me->totface; i++) {
+ if (tf[i].flag & TF_SELECT ) {
+ PyList_Append(l, PyList_GetItem(nm->faces, i));
+ }
+ }
+ }
+ return l;
+}
+
+
+static char NMesh_getActiveFace_doc[] = "returns the index of the active face ";
+static PyObject *NMesh_getActiveFace(PyObject *self, PyObject *args)
+{
+ if (((NMesh *)self)->sel_face < 0)
+ RETURN_INC(Py_None);
+ return Py_BuildValue("i", ((NMesh *)self)->sel_face);
+}
+
+static char NMesh_hasVertexUV_doc[] = "(flag = None) - returns 1 if Mesh has per vertex UVs ('Sticky')\n\
+The optional argument sets the Sticky flag";
+
+static PyObject *NMesh_hasVertexUV(PyObject *self, PyObject *args)
+{
+ NMesh *me= (NMesh *) self;
+ int flag;
+
+ if (args) {
+ if (PyArg_ParseTuple(args, "i", &flag)) {
+ if(flag) me->flags |= NMESH_HASVERTUV;
+ else me->flags &= ~NMESH_HASVERTUV;
+ }
+ }
+ PyErr_Clear();
+ if (me->flags & NMESH_HASVERTUV)
+ return BPY_incr_ret(Py_True);
+ else
+ return BPY_incr_ret(Py_False);
+}
+
+static char NMesh_hasFaceUV_doc[] = "(flag = None) - returns 1 if Mesh has textured faces\n\
+The optional argument sets the textured faces flag";
+
+static PyObject *NMesh_hasFaceUV(PyObject *self, PyObject *args)
+{
+ NMesh *me= (NMesh *) self;
+ int flag = -1;
+
+ BPY_TRY(PyArg_ParseTuple(args, "|i", &flag));
+
+ switch (flag) {
+ case 0:
+ me->flags |= NMESH_HASFACEUV;
+ break;
+ case 1:
+ me->flags &= ~NMESH_HASFACEUV;
+ break;
+ default:
+ break;
+ }
+
+ if (me->flags & NMESH_HASFACEUV)
+ return BPY_incr_ret(Py_True);
+ else
+ return BPY_incr_ret(Py_False);
+}
+
+
+static char NMesh_hasVertexColours_doc[] = "(flag = None) - returns 1 if Mesh has vertex colours.\n\
+The optional argument sets the vertex colour flag";
+
+static PyObject *NMesh_hasVertexColours(PyObject *self, PyObject *args)
+{
+ NMesh *me= (NMesh *) self;
+ int flag = -1;
+
+ BPY_TRY(PyArg_ParseTuple(args, "|i", &flag));
+
+ switch (flag) {
+ case 0:
+ me->flags &= ~NMESH_HASMCOL;
+ break;
+ case 1:
+ me->flags |= NMESH_HASMCOL;
+ break;
+ default:
+ break;
+ }
+
+ if (me->flags & NMESH_HASMCOL)
+ return BPY_incr_ret(Py_True);
+ else
+ return BPY_incr_ret(Py_False);
+
+}
+
+
+static char NMesh_update_doc[] = "updates the Mesh";
+static PyObject *NMesh_update(PyObject *self, PyObject *args)
+{
+ NMesh *nmesh= (NMesh *) self;
+ Mesh *mesh = nmesh->mesh;
+
+ if (mesh) {
+ unlink_existingMeshdata(mesh);
+ convert_NMeshToMesh(mesh, nmesh);
+ mesh_update(mesh);
+ } else {
+ nmesh->mesh = Mesh_fromNMesh(nmesh);
+ }
+
+ nmesh_updateMaterials(nmesh);
+/** This is another ugly fix due to the weird material handling of blender.
+ * it makes sure that object material lists get updated (by their length)
+ * according to their data material lists, otherwise blender crashes.
+ * It just stupidly runs through all objects...BAD BAD BAD.
+ */
+ test_object_materials((ID *)mesh);
+
+ if (!during_script())
+ allqueue(REDRAWVIEW3D, 0);
+ return PyInt_FromLong(1);
+
+}
+
+
+Mesh *Mesh_fromNMesh(NMesh *nmesh)
+{
+ Mesh *mesh= NULL;
+ mesh = mesh_new(); // new empty mesh Bobject
+ if (!mesh) {
+ PyErr_SetString(PyExc_RuntimeError, "FATAL: could not create mesh object");
+ return NULL;
+ }
+
+ convert_NMeshToMesh(mesh, nmesh);
+ mesh_update(mesh);
+ return mesh;
+}
+
+#ifdef EXPERIMENTAL
+
+static char NMesh_asMesh_doc[] = "returns free Mesh datablock object from NMesh";
+static PyObject *NMesh_asMesh(PyObject *self, PyObject *args)
+{
+ char *name= NULL;
+ Mesh *mesh= NULL;
+ NMesh *nmesh;
+ int recalc_normals= 1;
+
+ nmesh = (NMesh *) self;
+
+ BPY_TRY(PyArg_ParseTuple(args, "|si", &name, &recalc_normals));
+
+ if (!PySequence_Check(nmesh->verts))
+ return BPY_err_ret_ob(PyExc_AttributeError,
+ "nmesh vertices are not a sequence");
+ if (!PySequence_Check(nmesh->faces))
+ return BPY_err_ret_ob(PyExc_AttributeError,
+ "nmesh faces are not a sequence");
+ if (!PySequence_Check(nmesh->materials))
+ return BPY_err_ret_ob(PyExc_AttributeError,
+ "nmesh materials are not a sequence");
+ if (!BPY_check_sequence_consistency(nmesh->verts, &NMVert_Type))
+ return BPY_err_ret_ob(PyExc_AttributeError,
+ "nmesh vertices must be NMVerts");
+ if (!BPY_check_sequence_consistency(nmesh->faces, &NMFace_Type))
+ return BPY_err_ret_ob(PyExc_AttributeError,
+ "nmesh faces must be NMFaces");
+
+ mesh = Mesh_fromNMesh(nmesh);
+ return DataBlock_fromData(mesh);
+}
+
+#endif
+static char NMesh_link_doc[] = "(object) - Links NMesh data with Object 'object'";
+
+PyObject * NMesh_link(PyObject *self, PyObject *args)
+{
+ return DataBlock_link(self, args);
+}
+
+#undef MethodDef
+#define MethodDef(func) {#func, NMesh_##func, METH_VARARGS, NMesh_##func##_doc}
+
+static struct PyMethodDef NMesh_methods[] = {
+ MethodDef(hasVertexColours),
+ MethodDef(hasFaceUV),
+ MethodDef(hasVertexUV),
+ MethodDef(getActiveFace),
+ MethodDef(getSelectedFaces),
+ MethodDef(update),
+#ifdef EXPERIMENTAL
+ MethodDef(asMesh),
+#endif
+ {NULL, NULL}
+};
+
+static PyObject *NMesh_getattr(PyObject *self, char *name) {
+ NMesh *me= (NMesh *) self;
+
+ if (STREQ(name, "name"))
+ return BPY_incr_ret(me->name);
+
+ else if (STREQ(name, "block_type"))
+ return PyString_FromString("NMesh");
+
+ else if (STREQ(name, "materials"))
+ return BPY_incr_ret(me->materials);
+
+ else if (STREQ(name, "verts"))
+ return BPY_incr_ret(me->verts);
+
+ else if (STREQ(name, "users")) {
+ if (me->mesh) {
+ return PyInt_FromLong(me->mesh->id.us);
+ } else { // it's a free mesh:
+ return Py_BuildValue("i", 0);
+ }
+ }
+
+ else if (STREQ(name, "faces"))
+ return BPY_incr_ret(me->faces);
+
+ return Py_FindMethod(NMesh_methods, (PyObject*)self, name);
+
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+}
+
+static int NMesh_setattr(PyObject *self, char *name, PyObject *v) {
+ NMesh *me= (NMesh *) self;
+
+ if (STREQ3(name, "verts", "faces", "materials")) {
+ if(PySequence_Check(v)) {
+ if(STREQ(name, "materials")) {
+ Py_DECREF(me->materials);
+ me->materials= BPY_incr_ret(v);
+ } else if (STREQ(name, "verts")) {
+ Py_DECREF(me->verts);
+ me->verts= BPY_incr_ret(v);
+ } else {
+ Py_DECREF(me->faces);
+ me->faces= BPY_incr_ret(v);
+ }
+ } else {
+ PyErr_SetString(PyExc_AttributeError, "expected a sequence");
+ return -1;
+ }
+ } else {
+ PyErr_SetString(PyExc_AttributeError, name);
+ return -1;
+ }
+
+ return 0;
+}
+
+PyTypeObject NMesh_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "NMesh", /*tp_name*/
+ sizeof(NMesh), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor) NMesh_dealloc, /*tp_dealloc*/
+ (printfunc) 0, /*tp_print*/
+ (getattrfunc) NMesh_getattr, /*tp_getattr*/
+ (setattrfunc) NMesh_setattr, /*tp_setattr*/
+};
+
+static NMFace *nmface_from_data(NMesh *mesh, int vidxs[4], char mat_nr, char flag, TFace *tface, MCol *col)
+{
+ NMFace *newf= PyObject_NEW(NMFace, &NMFace_Type);
+ int i, len;
+
+ if(vidxs[3]) len= 4;
+ else if(vidxs[2]) len= 3;
+ else len= 2;
+
+ newf->v= PyList_New(len);
+
+ for (i=0; i<len; i++)
+ PyList_SetItem(newf->v, i, BPY_incr_ret(PyList_GetItem(mesh->verts, vidxs[i])));
+
+ if (tface) {
+ newf->uv = PyList_New(len); // per-face UV coordinates
+ for (i = 0; i < len; i++)
+ {
+ PyList_SetItem(newf->uv, i, Py_BuildValue("(ff)", tface->uv[i][0], tface->uv[i][1]));
+ }
+ if (tface->tpage)
+ newf->tpage = (DataBlock *) DataBlock_fromData((void *) tface->tpage); /* pointer to image per face */
+ else
+ newf->tpage = 0;
+ newf->mode = tface->mode; /* draw mode */
+ newf->flag = tface->flag; /* select flag */
+ newf->transp = tface->transp; /* transparency flag */
+ col = (MCol *) (tface->col);
+ } else {
+ newf->tpage = 0;
+ newf->uv = PyList_New(0);
+ }
+
+ newf->mat_nr= mat_nr;
+ newf->smooth= flag&ME_SMOOTH;
+
+ if (col) {
+ newf->col= PyList_New(4);
+ for(i=0; i<4; i++, col++)
+ PyList_SetItem(newf->col, i,
+ (PyObject *) newcol(col->b, col->g, col->r, col->a));
+ } else {
+ newf->col= PyList_New(0);
+ }
+ return newf;
+}
+
+static NMFace *nmface_from_shortdata(NMesh *mesh, MFace *face, TFace *tface, MCol *col)
+{
+ int vidxs[4];
+ vidxs[0]= face->v1;
+ vidxs[1]= face->v2;
+ vidxs[2]= face->v3;
+ vidxs[3]= face->v4;
+
+ return nmface_from_data(mesh, vidxs, face->mat_nr, face->flag, tface, col);
+}
+
+static NMFace *nmface_from_intdata(NMesh *mesh, MFaceInt *face, TFace *tface, MCol *col)
+{
+ int vidxs[4];
+ vidxs[0]= face->v1;
+ vidxs[1]= face->v2;
+ vidxs[2]= face->v3;
+ vidxs[3]= face->v4;
+
+ return nmface_from_data(mesh, vidxs, face->mat_nr, face->flag, tface, col);
+}
+
+static NMVert *nmvert_from_data(NMesh *me, MVert *vert, MSticky *st, float *co, int idx)
+{
+ NMVert *mv= PyObject_NEW(NMVert, &NMVert_Type);
+
+ VECCOPY (mv->co, co);
+
+ mv->no[0]= vert->no[0]/32767.0;
+ mv->no[1]= vert->no[1]/32767.0;
+ mv->no[2]= vert->no[2]/32767.0;
+
+ if (st) {
+ mv->uvco[0]= st->co[0];
+ mv->uvco[1]= st->co[1];
+ mv->uvco[2]= 0.0;
+
+ } else mv->uvco[0]= mv->uvco[1]= mv->uvco[2]= 0.0;
+
+ mv->index= idx;
+
+ return mv;
+}
+
+static int get_active_faceindex(Mesh *me)
+{
+ TFace *tf;
+ int i;
+
+ if (me == NULL) return -1;
+
+ tf = me->tface;
+ if (tf == 0) return -1;
+
+ for (i =0 ; i < me->totface; i++) {
+ if (tf[i].flag & TF_ACTIVE ) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+static PyObject *newNMesh_internal(Mesh *oldmesh, DispListMesh *dlm, float *extverts)
+{
+ NMesh *me= PyObject_NEW(NMesh, &NMesh_Type);
+ me->flags= 0;
+
+ if (!oldmesh) {
+ me->name= BPY_incr_ret(Py_None);
+ me->materials= PyList_New(0);
+ me->verts= PyList_New(0);
+ me->faces= PyList_New(0);
+ me->mesh= 0;
+ } else {
+ MVert *mverts;
+ MSticky *msticky;
+ MFaceInt *mfaceints;
+ MFace *mfaces;
+ TFace *tfaces;
+ MCol *mcols;
+ int i, totvert, totface;
+
+ if (dlm) {
+ me->name= BPY_incr_ret(Py_None);
+ me->mesh= 0;
+
+ msticky= NULL;
+ mfaces= NULL;
+ mverts= dlm->mvert;
+ mfaceints= dlm->mface;
+ tfaces= dlm->tface;
+ mcols= dlm->mcol;
+
+ totvert= dlm->totvert;
+ totface= dlm->totface;
+ } else {
+ me->name= PyString_FromString(oldmesh->id.name+2);
+ me->mesh= oldmesh;
+
+ mfaceints= NULL;
+ msticky= oldmesh->msticky;
+ mverts= oldmesh->mvert;
+ mfaces= oldmesh->mface;
+ tfaces= oldmesh->tface;
+ mcols= oldmesh->mcol;
+
+ totvert= oldmesh->totvert;
+ totface= oldmesh->totface;
+
+ me->sel_face= get_active_faceindex(oldmesh);
+ }
+
+ if (msticky) me->flags |= NMESH_HASVERTUV;
+ if (tfaces) me->flags |= NMESH_HASFACEUV;
+ if (mcols) me->flags |= NMESH_HASMCOL;
+
+ me->verts= PyList_New(totvert);
+ for (i=0; i<totvert; i++) {
+ MVert *oldmv= &mverts[i];
+ MSticky *oldst= msticky?&msticky[i]:NULL;
+ float *vco= extverts?&extverts[i*3]:oldmv->co;
+
+ PyList_SetItem(me->verts, i, (PyObject *) nmvert_from_data(me, oldmv, oldst, vco, i));
+ }
+
+ me->faces= PyList_New(totface);
+ for (i=0; i<totface; i++) {
+ TFace *oldtf= tfaces?&tfaces[i]:NULL;
+ MCol *oldmc= mcols?&mcols[i*4]:NULL;
+
+ if (mfaceints) {
+ MFaceInt *oldmf= &mfaceints[i];
+ PyList_SetItem(me->faces, i, (PyObject *) nmface_from_intdata(me, oldmf, oldtf, oldmc));
+ } else {
+ MFace *oldmf= &mfaces[i];
+ PyList_SetItem(me->faces, i, (PyObject *) nmface_from_shortdata(me, oldmf, oldtf, oldmc));
+ }
+ }
+ me->materials = PyList_fromMaterialList(oldmesh->mat, oldmesh->totcol);
+ }
+
+ return (PyObject *) me;
+}
+
+PyObject *newNMesh(Mesh *oldmesh)
+{
+ return newNMesh_internal(oldmesh, NULL, NULL);
+}
+
+static char NMeshmodule_New_doc[]=
+"() - returns a new, empty NMesh mesh object\n";
+
+static PyObject *NMeshmodule_New(PyObject *self, PyObject *args)
+{
+ return newNMesh(NULL);
+}
+
+static char NMeshmodule_GetRaw_doc[]=
+"([name]) - Get a raw mesh from Blender\n\
+\n\
+[name] Name of the mesh to be returned\n\
+\n\
+If name is not specified a new empty mesh is\n\
+returned, otherwise Blender returns an existing\n\
+mesh.";
+
+static PyObject *NMeshmodule_GetRaw(PyObject *self, PyObject *args)
+{
+ char *name=NULL;
+ Mesh *oldmesh=NULL;
+
+ BPY_TRY(PyArg_ParseTuple(args, "|s", &name));
+
+ if(name) {
+ oldmesh = (Mesh *) getFromList(getMeshList(), name);
+
+ if (!oldmesh) return BPY_incr_ret(Py_None);
+ }
+ return newNMesh(oldmesh);
+}
+
+static char NMeshmodule_GetRawFromObject_doc[]=
+"(name) - Get the raw mesh used by a Blender object\n"
+"\n"
+"(name) Name of the object to get the mesh from\n"
+"\n"
+"This returns the mesh as used by the object, which\n"
+"means it contains all deformations and modifications.";
+
+static PyObject *NMeshmodule_GetRawFromObject(PyObject *self, PyObject *args)
+{
+ char *name;
+ Object *ob;
+ PyObject *nmesh;
+
+ BPY_TRY(PyArg_ParseTuple(args, "s", &name));
+
+ ob= (Object*) getFromList(getObjectList(), name);
+ if (!ob)
+ return BPY_err_ret_ob(PyExc_AttributeError, name);
+ else if (ob->type!=OB_MESH)
+ return BPY_err_ret_ob(PyExc_AttributeError, "Object does not have Mesh data");
+ else {
+ Mesh *me= (Mesh*) ob->data;
+ DispList *dl;
+
+ if (mesh_uses_displist(me) && (dl= find_displist(&me->disp, DL_MESH)))
+ nmesh = newNMesh_internal(me, dl->mesh, NULL);
+ else if ((dl= find_displist(&ob->disp, DL_VERTS)))
+ nmesh = newNMesh_internal(me, NULL, dl->verts);
+ else
+ nmesh = newNMesh(me);
+ }
+ ((NMesh *) nmesh)->mesh = 0; // hack: to mark that (deformed) mesh is readonly,
+ // so the update function will not try to write it.
+ return nmesh;
+}
+
+static void mvert_from_data(MVert *mv, MSticky *st, NMVert *from)
+{
+ VECCOPY (mv->co, from->co);
+ mv->no[0]= from->no[0]*32767.0;
+ mv->no[1]= from->no[1]*32767.0;
+ mv->no[2]= from->no[2]*32767.0;
+
+ mv->flag= 0;
+ mv->mat_nr= 0;
+
+ if (st) {
+ st->co[0]= from->uvco[0];
+ st->co[1]= from->uvco[1];
+ }
+}
+
+/* TODO: this function is just a added hack. Don't look at the
+ * RGBA/BRGA confusion, it just works, but will never work with
+ * a restructured Blender */
+
+static void assign_perFaceColors(TFace *tf, NMFace *from)
+{
+ MCol *col;
+ int i;
+
+ col = (MCol *) (tf->col);
+
+ if (col) {
+ int len= PySequence_Length(from->col);
+
+ if(len>4) len= 4;
+
+ for (i=0; i<len; i++, col++) {
+ NMCol *mc= (NMCol *) PySequence_GetItem(from->col, i);
+ if(!NMCol_Check(mc)) {
+ Py_DECREF(mc);
+ continue;
+ }
+
+ col->r= mc->b;
+ col->b= mc->r;
+ col->g= mc->g;
+ col->a= mc->a;
+
+ Py_DECREF(mc);
+ }
+ }
+}
+
+static int assignFaceUV(TFace *tf, NMFace *nmface)
+{
+ PyObject *fuv, *tmp;
+ int i;
+
+ fuv = nmface->uv;
+ if (PySequence_Length(fuv) == 0)
+ return 0;
+ /* fuv = [(u_1, v_1), ... (u_n, v_n)] */
+ for (i = 0; i < PySequence_Length(fuv); i++) {
+ tmp = PyList_GetItem(fuv, i); /* stolen reference ! */
+ if (!PyArg_ParseTuple(tmp, "ff", &(tf->uv[i][0]), &(tf->uv[i][1])))
+ return 0;
+ }
+ if (nmface->tpage) /* image assigned ? */
+ {
+ tf->tpage = nmface->tpage->data;
+ }
+ else
+ tf->tpage = 0;
+
+ tf->mode = nmface->mode; /* copy mode */
+ tf->flag = nmface->flag; /* copy flag */
+ tf->transp = nmface->transp; /* copy transp flag */
+
+ /* assign vertex colours */
+ assign_perFaceColors(tf, nmface);
+ return 1;
+}
+
+static void mface_from_data(MFace *mf, TFace *tf, MCol *col, NMFace *from)
+{
+ NMVert *nmv;
+
+ int i= PyList_Size(from->v);
+ if(i>=1) {
+ nmv= (NMVert *) PyList_GetItem(from->v, 0);
+ if (NMVert_Check(nmv) && nmv->index!=-1) mf->v1= nmv->index;
+ else mf->v1= 0;
+ }
+ if(i>=2) {
+ nmv= (NMVert *) PyList_GetItem(from->v, 1);
+ if (NMVert_Check(nmv) && nmv->index!=-1) mf->v2= nmv->index;
+ else mf->v2= 0;
+ }
+ if(i>=3) {
+ nmv= (NMVert *) PyList_GetItem(from->v, 2);
+ if (NMVert_Check(nmv) && nmv->index!=-1) mf->v3= nmv->index;
+ else mf->v3= 0;
+ }
+ if(i>=4) {
+ nmv= (NMVert *) PyList_GetItem(from->v, 3);
+ if (NMVert_Check(nmv) && nmv->index!=-1) mf->v4= nmv->index;
+ else mf->v4= 0;
+ }
+
+ /* this function is evil:
+
+ test_index_mface(mf, i);
+
+ It rotates vertex indices, if there are illegal '0's (end marker)
+ in the vertex index list.
+ But it doesn't do that with vertex colours or texture coordinates...
+ */
+
+ if (tf) {
+ assignFaceUV(tf, from);
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ return;
+ }
+
+ test_index_face(mf, tf, i);
+ } else {
+ test_index_mface(mf, i);
+ }
+
+ mf->puno= 0;
+ mf->mat_nr= from->mat_nr;
+ mf->edcode= 0;
+ if (from->smooth)
+ mf->flag= ME_SMOOTH;
+ else
+ mf->flag= 0;
+
+ if (col) {
+ int len= PySequence_Length(from->col);
+
+ if(len>4) len= 4;
+
+ for (i=0; i<len; i++, col++) {
+ NMCol *mc= (NMCol *) PySequence_GetItem(from->col, i);
+ if(!NMCol_Check(mc)) {
+ Py_DECREF(mc);
+ continue;
+ }
+
+ col->b= mc->r;
+ col->g= mc->g;
+ col->r= mc->b;
+ col->a= mc->a;
+
+ Py_DECREF(mc);
+ }
+ }
+}
+
+
+/* check for a valid UV sequence */
+static int check_validFaceUV(NMesh *nmesh)
+{
+ PyObject *faces;
+ NMFace *nmface;
+ int i, n;
+
+ faces = nmesh->faces;
+ for (i = 0; i < PySequence_Length(faces); i++) {
+ nmface = (NMFace *) PyList_GetItem(faces, i);
+ n =
+ n = PySequence_Length(nmface->uv);
+ if (n != PySequence_Length(nmface->v))
+ {
+ if (n > 0)
+ printf("Warning: different length of vertex and UV coordinate "
+ "list in face!\n");
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int unlink_existingMeshdata(Mesh *mesh)
+{
+ freedisplist(&mesh->disp);
+ unlink_mesh(mesh);
+ if(mesh->mvert) MEM_freeN(mesh->mvert);
+ if(mesh->mface) MEM_freeN(mesh->mface);
+ if(mesh->mcol) MEM_freeN(mesh->mcol);
+ if(mesh->msticky) MEM_freeN(mesh->msticky);
+ if(mesh->mat) MEM_freeN(mesh->mat);
+ if(mesh->tface) MEM_freeN(mesh->tface);
+ return 1;
+}
+
+Material **nmesh_updateMaterials(NMesh *nmesh)
+{
+ Material **matlist;
+ Mesh *mesh = nmesh->mesh;
+ int len = PySequence_Length(nmesh->materials);
+
+ if (!mesh) {
+ printf("FATAL INTERNAL ERROR: illegal call to updateMaterials()\n");
+ return 0;
+ }
+
+ if (len > 0) {
+ matlist = newMaterialList_fromPyList(nmesh->materials);
+ if (mesh->mat)
+ MEM_freeN(mesh->mat);
+ mesh->mat = matlist;
+ } else {
+ matlist = 0;
+ }
+ mesh->totcol = len;
+ return matlist;
+}
+
+PyObject *NMesh_assignMaterials_toObject(NMesh *nmesh, Object *ob)
+{
+ DataBlock *block;
+ Material *ma;
+ int i;
+ short old_matmask;
+
+ old_matmask = ob->colbits; // HACK: save previous colbits
+ ob->colbits = 0; // make assign_material work on mesh linked material
+
+ for (i= 0; i < PySequence_Length(nmesh->materials); i++) {
+ block= (DataBlock *) PySequence_GetItem(nmesh->materials, i);
+
+ if (DataBlock_isType(block, ID_MA)) {
+ ma = (Material *) block->data;
+ assign_material(ob, ma, i+1); // XXX don't use this function anymore
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "Material type in attribute list 'materials' expected!");
+ Py_DECREF(block);
+ return NULL;
+ }
+
+ Py_DECREF(block);
+ }
+ ob->colbits = old_matmask; // HACK
+
+ ob->actcol = 1;
+ RETURN_INC(Py_None);
+}
+
+static int convert_NMeshToMesh(Mesh *mesh, NMesh *nmesh)
+{
+ MFace *newmf;
+ TFace *newtf;
+ MVert *newmv;
+ MSticky *newst;
+ MCol *newmc;
+
+ int i, j;
+
+ mesh->mvert= NULL;
+ mesh->mface= NULL;
+ mesh->mcol= NULL;
+ mesh->msticky= NULL;
+ mesh->tface = NULL;
+ mesh->mat= NULL;
+
+ // material assignment moved to PutRaw
+ mesh->totvert= PySequence_Length(nmesh->verts);
+ if (mesh->totvert) {
+ if (nmesh->flags&NMESH_HASVERTUV)
+ mesh->msticky= MEM_callocN(sizeof(MSticky)*mesh->totvert, "msticky");
+
+ mesh->mvert= MEM_callocN(sizeof(MVert)*mesh->totvert, "mverts");
+ }
+
+ if (mesh->totvert)
+ mesh->totface= PySequence_Length(nmesh->faces);
+ else
+ mesh->totface= 0;
+
+
+ if (mesh->totface) {
+
+/* only create vertcol array if mesh has no texture faces */
+
+/* TODO: get rid of double storage of vertex colours. In a mesh,
+ * vertex colors can be stored the following ways:
+ * - per (TFace*)->col
+ * - per (Mesh*)->mcol
+ * This is stupid, but will reside for the time being -- at least until
+ * a redesign of the internal Mesh structure */
+
+ if (!(nmesh->flags & NMESH_HASFACEUV) && (nmesh->flags&NMESH_HASMCOL))
+ mesh->mcol= MEM_callocN(4*sizeof(MCol)*mesh->totface, "mcol");
+
+ mesh->mface= MEM_callocN(sizeof(MFace)*mesh->totface, "mfaces");
+ }
+
+ /* This stuff here is to tag all the vertices referenced
+ * by faces, then untag the vertices which are actually
+ * in the vert list. Any vertices untagged will be ignored
+ * by the mface_from_data function. It comes from my
+ * screwed up decision to not make faces only store the
+ * index. - Zr
+ */
+ for (i=0; i<mesh->totface; i++) {
+ NMFace *mf= (NMFace *) PySequence_GetItem(nmesh->faces, i);
+
+ j= PySequence_Length(mf->v);
+ while (j--) {
+ NMVert *mv= (NMVert *) PySequence_GetItem(mf->v, j);
+ if (NMVert_Check(mv)) mv->index= -1;
+ Py_DECREF(mv);
+ }
+
+ Py_DECREF(mf);
+ }
+
+ for (i=0; i<mesh->totvert; i++) {
+ NMVert *mv= (NMVert *) PySequence_GetItem(nmesh->verts, i);
+ mv->index= i;
+ Py_DECREF(mv);
+ }
+
+ newmv= mesh->mvert;
+ newst= mesh->msticky;
+ for (i=0; i<mesh->totvert; i++) {
+ PyObject *mv= PySequence_GetItem(nmesh->verts, i);
+ mvert_from_data(newmv, newst, (NMVert *)mv);
+ Py_DECREF(mv);
+
+ newmv++;
+ if (newst) newst++;
+ }
+
+/* assign per face texture UVs */
+
+ /* check face UV flag, then check whether there was one
+ * UV coordinate assigned, if yes, make tfaces */
+ if ((nmesh->flags & NMESH_HASFACEUV) || (check_validFaceUV(nmesh))) {
+ make_tfaces(mesh); /* initialize TFaces */
+
+ newmc= mesh->mcol;
+ newmf= mesh->mface;
+ newtf= mesh->tface;
+ for (i=0; i<mesh->totface; i++) {
+ PyObject *mf= PySequence_GetItem(nmesh->faces, i);
+ mface_from_data(newmf, newtf, newmc, (NMFace *) mf);
+ Py_DECREF(mf);
+
+ newtf++;
+ newmf++;
+ if (newmc) newmc++;
+ }
+
+ nmesh->flags |= NMESH_HASFACEUV;
+ } else {
+
+ newmc= mesh->mcol;
+ newmf= mesh->mface;
+ for (i=0; i<mesh->totface; i++) {
+ PyObject *mf= PySequence_GetItem(nmesh->faces, i);
+ mface_from_data(newmf, 0, newmc, (NMFace *) mf);
+ Py_DECREF(mf);
+
+ newmf++;
+ if (newmc) newmc++;
+ }
+ }
+ return 1;
+}
+
+
+
+static char NMeshmodule_PutRaw_doc[]=
+"(mesh, [name, renormal]) - Return a raw mesh to Blender\n\
+\n\
+(mesh) The NMesh object to store\n\
+[name] The mesh to replace\n\
+[renormal=1] Flag to control vertex normal recalculation\n\
+\n\
+If the name of a mesh to replace is not given a new\n\
+object is created and returned.";
+
+static PyObject *NMeshmodule_PutRaw(PyObject *self, PyObject *args)
+{
+ char *name= NULL;
+ Mesh *mesh= NULL;
+ Object *ob= NULL;
+ NMesh *nmesh;
+ int recalc_normals= 1;
+
+ BPY_TRY(PyArg_ParseTuple(args, "O!|si", &NMesh_Type, &nmesh, &name, &recalc_normals));
+
+ if (!PySequence_Check(nmesh->verts))
+ return BPY_err_ret_ob(PyExc_AttributeError, "nmesh vertices are not a sequence");
+ if (!PySequence_Check(nmesh->faces))
+ return BPY_err_ret_ob(PyExc_AttributeError, "nmesh faces are not a sequence");
+ if (!PySequence_Check(nmesh->materials))
+ return BPY_err_ret_ob(PyExc_AttributeError, "nmesh materials are not a sequence");
+
+ if (!BPY_check_sequence_consistency(nmesh->verts, &NMVert_Type))
+ return BPY_err_ret_ob(PyExc_AttributeError, "nmesh vertices must be NMVerts");
+ if (!BPY_check_sequence_consistency(nmesh->faces, &NMFace_Type))
+ return BPY_err_ret_ob(PyExc_AttributeError, "nmesh faces must be NMFaces");
+
+ if (name)
+ mesh= (Mesh *) getFromList(getMeshList(), name);
+ /* returns new mesh if not found */
+
+ if(!mesh || mesh->id.us==0) {
+ ob= add_object(OB_MESH);
+ if (!ob) {
+ PyErr_SetString(PyExc_RuntimeError, "Fatal: could not create mesh object");
+ return 0;
+ }
+ if (mesh)
+ set_mesh(ob, mesh);
+ else
+ mesh= (Mesh *) ob->data;
+ }
+ if(name) new_id(getMeshList(), &mesh->id, name);
+
+ unlink_existingMeshdata(mesh);
+ convert_NMeshToMesh(mesh, nmesh);
+ nmesh->mesh = mesh;
+
+ if(recalc_normals)
+ vertexnormals_mesh(mesh, 0);
+
+ mesh_update(mesh);
+
+ if (!during_script())
+ allqueue(REDRAWVIEW3D, 0);
+
+ // OK...this requires some explanation:
+ // Materials can be assigned two ways:
+ // a) to the object data (in this case, the mesh)
+ // b) to the Object
+ //
+ // Case a) is wanted, if Mesh data should be shared among objects,
+ // as well as its materials (up to 16)
+ // Case b) is wanted, when Mesh data should be shared, but not the
+ // materials. For example, you want several checker boards sharing their
+ // mesh data, but having different colors. So you would assign material
+ // index 0 to all even, index 1 to all odd faces and bind the materials
+ // to the Object instead (MaterialButtons: [OB] button "link materials to object")
+ //
+ // This feature implies that pointers to materials can be stored in
+ // an object or a mesh. The number of total materials MUST be
+ // synchronized (ob->totcol <-> mesh->totcol). We avoid the dangerous
+ // direct access by calling blenderkernel/material.c:assign_material().
+
+ // The flags setting the material binding is found in ob->colbits, where
+ // each bit indicates the binding PER MATERIAL
+
+ if (ob) { // we created a new object
+ NMesh_assignMaterials_toObject(nmesh, ob);
+ return DataBlock_fromData(ob);
+ } else {
+ RETURN_INC(Py_None);
+ }
+}
+
+#undef MethodDef
+#define MethodDef(func) {#func, NMeshmodule_##func, METH_VARARGS, NMeshmodule_##func##_doc}
+
+static struct PyMethodDef NMeshmodule_methods[] = {
+// These should be: Mesh.Col, Mesh.Vert, Mesh.Face in fure
+// -- for ownership reasons
+ MethodDef(Col),
+ MethodDef(Vert),
+ MethodDef(Face),
+ MethodDef(New),
+ MethodDef(GetRaw),
+ MethodDef(GetRawFromObject),
+ MethodDef(PutRaw),
+ {NULL, NULL}
+};
+#undef BPY_ADDCONST
+#define BPY_ADDCONST(dict, name) insertConst(dict, #name, PyInt_FromLong(TF_##name))
+
+/* set constants for face drawing mode -- see drawmesh.c */
+
+static void init_NMeshConst(PyObject *d)
+{
+ insertConst(d, "BILLBOARD", PyInt_FromLong(TF_BILLBOARD2));
+ //BPY_ADDCONST(d, BILLBOARD);
+ insertConst(d, "ALL", PyInt_FromLong(0xffff));
+ BPY_ADDCONST(d, DYNAMIC);
+ BPY_ADDCONST(d, INVISIBLE);
+ insertConst(d, "HALO", PyInt_FromLong(TF_BILLBOARD));
+ BPY_ADDCONST(d, LIGHT);
+ BPY_ADDCONST(d, OBCOL);
+ BPY_ADDCONST(d, SHADOW);
+ BPY_ADDCONST(d, SHAREDVERT);
+ BPY_ADDCONST(d, SHAREDCOL);
+ BPY_ADDCONST(d, TEX);
+ BPY_ADDCONST(d, TILES);
+ BPY_ADDCONST(d, TWOSIDE);
+/* transparent modes */
+ BPY_ADDCONST(d, SOLID);
+ BPY_ADDCONST(d, ADD);
+ BPY_ADDCONST(d, ALPHA);
+ BPY_ADDCONST(d, SUB);
+/* TFACE flags */
+ BPY_ADDCONST(d, SELECT);
+ BPY_ADDCONST(d, HIDE);
+ BPY_ADDCONST(d, ACTIVE);
+}
+
+PyObject *init_py_nmesh(void)
+{
+ PyObject *d;
+ PyObject *mod= Py_InitModule(SUBMODULE(NMesh), NMeshmodule_methods);
+ PyObject *dict= PyModule_GetDict(mod);
+
+ NMesh_Type.ob_type= &PyType_Type;
+ NMVert_Type.ob_type= &PyType_Type;
+ NMFace_Type.ob_type= &PyType_Type;
+ NMCol_Type.ob_type= &PyType_Type;
+
+ d = ConstObject_New();
+ PyDict_SetItemString(dict, "Const" , d);
+ init_NMeshConst(d);
+
+ g_nmeshmodule = mod;
+ return mod;
+}
+
+#ifdef SHAREDMODULE
+void initNMesh(void)
+{
+ init_py_nmesh();
+}
+#endif
diff --git a/source/blender/bpython/intern/opy_nmesh.h b/source/blender/bpython/intern/opy_nmesh.h
new file mode 100644
index 00000000000..778a726b26e
--- /dev/null
+++ b/source/blender/bpython/intern/opy_nmesh.h
@@ -0,0 +1,93 @@
+/**
+ * $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 *****
+ */
+/* opy_nmesh.c */
+
+#include "DNA_mesh_types.h"
+
+#define NMesh_Check(v) ((v)->ob_type == &NMesh_Type)
+#define NMFace_Check(v) ((v)->ob_type == &NMFace_Type)
+#define NMVert_Check(v) ((v)->ob_type == &NMVert_Type)
+#define NMCol_Check(v) ((v)->ob_type == &NMCol_Type)
+
+typedef struct _NMCol {
+ PyObject_HEAD
+
+ unsigned char r, g, b, a;
+} NMCol;
+
+struct PyBlock;
+
+typedef struct _NMFace {
+ PyObject_HEAD
+
+ PyObject *v;
+ PyObject *uv;
+ PyObject *col;
+ short mode;
+ short flag;
+ unsigned char transp;
+ DataBlock *tpage; /* Image */
+ char mat_nr, smooth;
+} NMFace;
+
+typedef struct _NMesh {
+ PyObject_HEAD
+ Mesh *mesh;
+ PyObject *name;
+ PyObject *materials;
+ PyObject *verts;
+ PyObject *faces;
+ int sel_face; /* XXX remove */
+ char flags;
+#define NMESH_HASMCOL 1<<0
+#define NMESH_HASVERTUV 1<<1
+#define NMESH_HASFACEUV 1<<2
+
+} NMesh;
+
+typedef struct _NMVert {
+ PyObject_VAR_HEAD
+
+ float co[3];
+ float no[3];
+ float uvco[3];
+
+ int index;
+} NMVert;
+
+
+/* PROTOS */
+
+PyObject *newNMesh(Mesh *oldmesh);
+Mesh *Mesh_fromNMesh(NMesh *nmesh);
+PyObject *NMesh_assignMaterials_toObject(NMesh *nmesh, Object *ob);
+Material **nmesh_updateMaterials(NMesh *nmesh);
diff --git a/source/blender/bpython/intern/opy_vector.c b/source/blender/bpython/intern/opy_vector.c
new file mode 100644
index 00000000000..905c6aeed34
--- /dev/null
+++ b/source/blender/bpython/intern/opy_vector.c
@@ -0,0 +1,241 @@
+/* python.c MIXED MODEL
+ *
+ * june 99
+ * $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_tools.h"
+#include "BPY_macros.h"
+#include "BPY_modules.h"
+#include "opy_vector.h"
+
+
+
+/*****************************/
+/* Vector Python Object */
+/*****************************/
+
+PyTypeObject Vector_Type;
+
+
+#define VectorObject_Check(v) ((v)->ob_type == &Vector_Type)
+
+
+static void Vector_dealloc(VectorObject *self) {
+ PyMem_DEL(self);
+}
+
+static PyObject *Vector_getattr(VectorObject *self, char *name) {
+ if (self->size==3 && ELEM3(name[0], 'x', 'y', 'z') && name[1]==0)
+ return PyFloat_FromDouble(self->vec[ name[0]-'x' ]);
+
+ PyErr_SetString(PyExc_AttributeError, name);
+ return NULL;
+}
+
+static int Vector_setattr(VectorObject *self, char *name, PyObject *v) {
+ float val;
+
+ BPY_TRY(PyArg_Parse(v, "f;Coordinates must be floats", &val));
+
+ if (self->size==3 && ELEM3(name[0], 'x', 'y', 'z') && name[1]==0)
+ self->vec[ name[0]-'x' ]= val;
+ else
+ return -1;
+
+ return 0;
+}
+
+/* Vectors utils */
+
+/* XXX
+int Vector_Parse(PyObject *vec)
+{
+
+}
+*/
+
+/* Vectors Sequence methods */
+
+static int Vector_len(VectorObject *self)
+{
+ return self->size;
+}
+
+static PyObject *Vector_item(VectorObject *self, int i)
+{
+ if (i < 0 || i >= self->size) {
+ PyErr_SetString(PyExc_IndexError, "array index out of range");
+ return NULL;
+ }
+ return Py_BuildValue("f", self->vec[i]);
+}
+
+static PyObject *Vector_slice(VectorObject *self, int begin, int end)
+{
+ PyObject *list;
+ int count;
+
+ if (begin<0) begin= 0;
+ if (end>self->size) end= self->size;
+ if (begin>end) begin= end;
+
+ list= PyList_New(end-begin);
+
+ for (count= begin; count<end; count++)
+ PyList_SetItem(list, count-begin, PyFloat_FromDouble(self->vec[count]));
+
+ return list;
+}
+
+static int Vector_ass_item(VectorObject *self, int i, PyObject *ob)
+{
+ if (i < 0 || i >= self->size) {
+ PyErr_SetString(PyExc_IndexError, "array assignment index out of range");
+ return -1;
+ }
+
+ if (!PyNumber_Check(ob)) {
+ PyErr_SetString(PyExc_IndexError, "vector member must be a number");
+ return -1;
+ }
+
+ self->vec[i]= PyFloat_AsDouble(ob);
+/* if(!PyArg_Parse(ob, "f", &)) return -1; */
+
+ return 0;
+}
+
+static int Vector_ass_slice(VectorObject *self, int begin, int end, PyObject *seq)
+{
+ int count;
+
+ if (begin<0) begin= 0;
+ if (end>self->size) end= self->size;
+ if (begin>end) begin= end;
+
+ if (!PySequence_Check(seq)) {
+ PyErr_SetString(PyExc_TypeError, "illegal argument type for built-in operation");
+ return -1;
+ }
+
+ if (PySequence_Length(seq)!=(end-begin)) {
+ PyErr_SetString(PyExc_TypeError, "size mismatch in slice assignment");
+ return -1;
+ }
+
+ for (count= begin; count<end; count++) {
+ PyObject *ob= PySequence_GetItem(seq, count);
+ if (!PyArg_Parse(ob, "f", &self->vec[count])) {
+ Py_DECREF(ob);
+ return -1;
+ }
+ Py_DECREF(ob);
+ }
+
+ return 0;
+}
+
+PyObject *BPY_tuple_repr(PyObject *self, int size)
+{
+ PyObject *repr, *comma, *item;
+ int i;
+
+ // note: a value must be built because the list is decrefed!
+ // otherwise we have nirvana pointers inside python..
+ //PyObject *repr= Py_BuildValue("s", PyString_AsString(PyObject_Repr(list)));
+ repr = PyString_FromString("(");
+ if (!repr) return 0;
+
+ item = PySequence_GetItem(self, 0);
+ PyString_ConcatAndDel(&repr, PyObject_Repr(item));
+ Py_DECREF(item);
+
+ comma = PyString_FromString(", ");
+ for (i = 1; i < size; i++) {
+ PyString_Concat(&repr, comma);
+ item = PySequence_GetItem(self, i);
+ PyString_ConcatAndDel(&repr, PyObject_Repr(item));
+ Py_DECREF(item);
+ }
+ PyString_ConcatAndDel(&repr, PyString_FromString(")"));
+ Py_DECREF(comma);
+ return repr;
+
+}
+
+
+static PyObject *Vector_repr (VectorObject *self) {
+ return BPY_tuple_repr((PyObject *) self, self->size);
+}
+
+static PySequenceMethods Vector_SeqMethods = {
+ (inquiry) Vector_len, /* sq_length */
+ (binaryfunc) 0, /* sq_concat */
+ (intargfunc) 0, /* sq_repeat */
+ (intargfunc) Vector_item, /* sq_item */
+ (intintargfunc) Vector_slice, /* sq_slice */
+ (intobjargproc) Vector_ass_item, /* sq_ass_item */
+ (intintobjargproc) Vector_ass_slice, /* sq_ass_slice */
+};
+
+PyTypeObject Vector_Type = {
+ PyObject_HEAD_INIT(NULL)
+ 0, /*ob_size*/
+ "Vector", /*tp_name*/
+ sizeof(VectorObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ (destructor) Vector_dealloc, /*tp_dealloc*/
+ (printfunc) 0, /*tp_print*/
+ (getattrfunc) Vector_getattr, /*tp_getattr*/
+ (setattrfunc) Vector_setattr, /*tp_setattr*/
+ 0, /*tp_compare*/
+ (reprfunc) Vector_repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &Vector_SeqMethods, /*tp_as_sequence*/
+};
+
+PyObject *newVectorObject(float *vec, int size) {
+ VectorObject *self;
+
+ self= PyObject_NEW(VectorObject, &Vector_Type);
+
+ self->vec= vec;
+ self->size= size;
+
+ return (PyObject*) self;
+}
+
+void init_py_vector(void) {
+ Vector_Type.ob_type = &PyType_Type;
+}
diff --git a/source/blender/bpython/intern/opy_vector.h b/source/blender/bpython/intern/opy_vector.h
new file mode 100644
index 00000000000..cf7ca87fd6a
--- /dev/null
+++ b/source/blender/bpython/intern/opy_vector.h
@@ -0,0 +1,63 @@
+
+
+/* Matrix and vector objects in Python */
+
+/* $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 *****
+ *
+ */
+
+/*****************************/
+/* Matrix Python Object */
+/*****************************/
+/* temporar hack for typecasts */
+
+typedef float (*Matrix4Ptr)[4];
+typedef struct {
+ PyObject_VAR_HEAD
+ float *vec;
+ int size;
+} VectorObject;
+
+typedef struct {
+ PyObject_VAR_HEAD
+ PyObject *rows[4];
+ Matrix4Ptr mat;
+} MatrixObject;
+
+
+/* PROTOS */
+
+PyObject *newVectorObject(float *vec, int size);
+PyObject *newMatrixObject(Matrix4Ptr mat);
+void init_py_matrix(void);
+void init_py_vector(void);
+
+
diff --git a/source/blender/bpython/intern/opy_window.c b/source/blender/bpython/intern/opy_window.c
new file mode 100644
index 00000000000..8aa976382a9
--- /dev/null
+++ b/source/blender/bpython/intern/opy_window.c
@@ -0,0 +1,194 @@
+
+/*
+ * Python Blender Window module
+ *
+ * $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 "b_interface.h"
+#include "BPY_tools.h"
+#include "BPY_main.h"
+#include "BPY_window.h"
+
+#include "BSE_headerbuttons.h"
+
+#include "BIF_screen.h" // curarea
+#include "BIF_space.h" // allqueue()
+#include "BIF_drawtext.h" // pop_space_text
+#include "mydevice.h" // for all the event constants
+
+#include "opy_datablock.h"
+#include "opy_nmesh.h"
+
+#include "DNA_view3d_types.h"
+#include "DNA_space_types.h"
+
+
+/*********************************/
+/* helper routines */
+
+
+/** update current camera view */
+
+void window_update_curCamera(Object *camera)
+{
+ copy_view3d_lock(REDRAW);
+}
+
+char Windowmodule_QRedrawAll_doc[]= "() - Redraw all windows by queue event";
+
+/* hack to flag that window redraw has happened inside slider callback: */
+int g_window_redrawn = 0;
+
+static PyObject *Windowmodule_QRedrawAll(PyObject *self, PyObject *args)
+{
+ int wintype = 0;
+ BPY_TRY(PyArg_ParseTuple(args, "|i", &wintype));
+
+ allqueue(REDRAWALL, 0);
+ RETURN_INC(Py_None);
+}
+char Windowmodule_Redraw_doc[]= "() - Force a redraw of a specific Window Type; see Window.Const";
+
+PyObject *Windowmodule_Redraw(PyObject *self, PyObject *args)
+{
+ ScrArea *tempsa, *sa;
+ SpaceText *st;
+ int wintype = SPACE_VIEW3D;
+ short redraw_all = 0;
+
+ BPY_TRY(PyArg_ParseTuple(args, "|i", &wintype));
+
+ g_window_redrawn = 1;
+
+ if (wintype < 0)
+ redraw_all = 1;
+ if (!during_script()) {
+ tempsa= curarea;
+ sa= getGlobal()->curscreen->areabase.first;
+ while(sa) {
+
+ if (sa->spacetype== wintype || redraw_all) {
+ /* don't force-redraw Text window (Python GUI) when
+ redraw is called out of a slider update */
+ if (sa->spacetype == SPACE_TEXT) {
+ st = sa->spacedata.first;
+ if (st->text->flags & TXT_FOLLOW) // follow cursor display
+ pop_space_text(st);
+ if (disable_force_draw) {
+ scrarea_queue_redraw(sa);
+ }
+
+
+ } else {
+ scrarea_do_windraw(sa);
+ if (sa->headwin) scrarea_do_headdraw(sa);
+ }
+ }
+
+ sa= sa->next;
+ }
+ if(curarea!=tempsa) areawinset(tempsa->win);
+
+ if (curarea->headwin) scrarea_do_headdraw(curarea);
+ screen_swapbuffers();
+ }
+
+ RETURN_INC(Py_None);
+}
+
+char Windowmodule_RedrawAll_doc[]= "() - Redraw all windows";
+static PyObject *Windowmodule_RedrawAll(PyObject *self, PyObject *args)
+{
+ return Windowmodule_Redraw(self, Py_BuildValue("(i)", -1));
+}
+
+char Windowmodule_draw_progressbar_doc[]= "(done, text) - Draw a progressbar.\n\
+'done' is a float value <= 1.0, 'text' contains info about what is currently\n\
+being done";
+
+static PyObject *Windowmodule_draw_progressbar(PyObject *self, PyObject *args)
+{
+ float done;
+ char *info = 0;
+ int retval;
+
+ BPY_TRY(PyArg_ParseTuple(args, "fs", &done, &info));
+ retval = progress_bar(done, info);
+ return Py_BuildValue("i", retval);
+}
+
+#undef METHODDEF
+#define METHODDEF(func) {#func, Windowmodule_##func, METH_VARARGS, Windowmodule_##func##_doc}
+
+static struct PyMethodDef Windowmodule_methods[] = {
+ METHODDEF(Redraw),
+ METHODDEF(QRedrawAll),
+ METHODDEF(RedrawAll),
+ METHODDEF(draw_progressbar),
+
+ {NULL, NULL}
+};
+
+
+#undef BPY_ADDCONST
+#define BPY_ADDCONST(dict, name) insertConst(dict, #name, PyInt_FromLong(SPACE_##name))
+
+PyObject *INITMODULE(Window)(void)
+{
+ PyObject *d;
+ PyObject *mod= Py_InitModule(SUBMODULE(Window), Windowmodule_methods);
+ PyObject *dict= PyModule_GetDict(mod);
+
+/* from DNA_screen.types.h */
+ d = ConstObject_New();
+ PyDict_SetItemString(dict, "Types" , d);
+
+ BPY_ADDCONST(d, VIEW3D);
+ BPY_ADDCONST(d, IPO);
+ BPY_ADDCONST(d, OOPS);
+ BPY_ADDCONST(d, BUTS);
+ BPY_ADDCONST(d, FILE);
+ BPY_ADDCONST(d, IMAGE);
+ BPY_ADDCONST(d, INFO);
+ BPY_ADDCONST(d, SEQ);
+ BPY_ADDCONST(d, IMASEL);
+ BPY_ADDCONST(d, SOUND);
+ BPY_ADDCONST(d, ACTION);
+ BPY_ADDCONST(d, TEXT);
+ BPY_ADDCONST(d, NLA);
+/* BPY_ADDCONST(d, LOGIC); */
+
+ return mod;
+}