Initial revision
This commit is contained in:
183
source/blender/bpython/intern/BPY_constobject.c
Normal file
183
source/blender/bpython/intern/BPY_constobject.c
Normal file
@@ -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*/
|
||||
};
|
||||
|
40
source/blender/bpython/intern/BPY_constobject.h
Normal file
40
source/blender/bpython/intern/BPY_constobject.h
Normal file
@@ -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);
|
||||
|
239
source/blender/bpython/intern/BPY_csg.c
Normal file
239
source/blender/bpython/intern/BPY_csg.c
Normal file
@@ -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);
|
||||
|
||||
}
|
||||
|
35
source/blender/bpython/intern/BPY_csg.h
Normal file
35
source/blender/bpython/intern/BPY_csg.h
Normal file
@@ -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"
|
103
source/blender/bpython/intern/BPY_image.c
Normal file
103
source/blender/bpython/intern/BPY_image.c
Normal file
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
717
source/blender/bpython/intern/BPY_ipo.c
Normal file
717
source/blender/bpython/intern/BPY_ipo.c
Normal file
@@ -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;
|
||||
}
|
96
source/blender/bpython/intern/BPY_links.c
Normal file
96
source/blender/bpython/intern/BPY_links.c
Normal file
@@ -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
|
62
source/blender/bpython/intern/BPY_listbase_macro.h
Normal file
62
source/blender/bpython/intern/BPY_listbase_macro.h
Normal file
@@ -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 *)
|
268
source/blender/bpython/intern/BPY_macros.h
Normal file
268
source/blender/bpython/intern/BPY_macros.h
Normal file
@@ -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)
|
672
source/blender/bpython/intern/BPY_main.c
Normal file
672
source/blender/bpython/intern/BPY_main.c
Normal file
@@ -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...
|
86
source/blender/bpython/intern/BPY_main.h
Normal file
86
source/blender/bpython/intern/BPY_main.h
Normal file
@@ -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);
|
47
source/blender/bpython/intern/BPY_modules.h
Normal file
47
source/blender/bpython/intern/BPY_modules.h
Normal file
@@ -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);
|
||||
|
||||
|
||||
|
499
source/blender/bpython/intern/BPY_object.c
Normal file
499
source/blender/bpython/intern/BPY_object.c
Normal file
@@ -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;
|
||||
}
|
||||
|
506
source/blender/bpython/intern/BPY_scene.c
Normal file
506
source/blender/bpython/intern/BPY_scene.c
Normal file
@@ -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, ¤t));
|
||||
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;
|
||||
}
|
||||
|
||||
|
295
source/blender/bpython/intern/BPY_text.c
Normal file
295
source/blender/bpython/intern/BPY_text.c
Normal file
@@ -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}
|
||||
};
|
||||
|
106
source/blender/bpython/intern/BPY_tools.c
Normal file
106
source/blender/bpython/intern/BPY_tools.c
Normal file
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
37
source/blender/bpython/intern/BPY_tools.h
Normal file
37
source/blender/bpython/intern/BPY_tools.h
Normal file
@@ -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);
|
39
source/blender/bpython/intern/BPY_types.h
Normal file
39
source/blender/bpython/intern/BPY_types.h
Normal file
@@ -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[];
|
33
source/blender/bpython/intern/BPY_window.h
Normal file
33
source/blender/bpython/intern/BPY_window.h
Normal file
@@ -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);
|
||||
|
75
source/blender/bpython/intern/Makefile
Normal file
75
source/blender/bpython/intern/Makefile
Normal file
@@ -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..
|
||||
|
22
source/blender/bpython/intern/README
Normal file
22
source/blender/bpython/intern/README
Normal file
@@ -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..
|
||||
|
87
source/blender/bpython/intern/api.h
Normal file
87
source/blender/bpython/intern/api.h
Normal file
@@ -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
|
191
source/blender/bpython/intern/b_import.c
Normal file
191
source/blender/bpython/intern/b_import.c
Normal file
@@ -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);
|
||||
}
|
||||
|
35
source/blender/bpython/intern/b_import.h
Normal file
35
source/blender/bpython/intern/b_import.h
Normal file
@@ -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);
|
753
source/blender/bpython/intern/b_interface.c
Normal file
753
source/blender/bpython/intern/b_interface.c
Normal file
@@ -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;
|
||||
}
|
||||
|
184
source/blender/bpython/intern/b_interface.h
Normal file
184
source/blender/bpython/intern/b_interface.h
Normal file
@@ -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 */
|
||||
|
||||
|
||||
|
342
source/blender/bpython/intern/opy_blender.c
Normal file
342
source/blender/bpython/intern/opy_blender.c
Normal file
@@ -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));
|
||||
}
|
||||
|
1299
source/blender/bpython/intern/opy_datablock.c
Normal file
1299
source/blender/bpython/intern/opy_datablock.c
Normal file
File diff suppressed because it is too large
Load Diff
193
source/blender/bpython/intern/opy_datablock.h
Normal file
193
source/blender/bpython/intern/opy_datablock.h
Normal file
@@ -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);
|
2679
source/blender/bpython/intern/opy_draw.c
Normal file
2679
source/blender/bpython/intern/opy_draw.c
Normal file
File diff suppressed because it is too large
Load Diff
173
source/blender/bpython/intern/opy_matrix.c
Normal file
173
source/blender/bpython/intern/opy_matrix.c
Normal file
@@ -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;
|
||||
}
|
1716
source/blender/bpython/intern/opy_nmesh.c
Normal file
1716
source/blender/bpython/intern/opy_nmesh.c
Normal file
File diff suppressed because it is too large
Load Diff
93
source/blender/bpython/intern/opy_nmesh.h
Normal file
93
source/blender/bpython/intern/opy_nmesh.h
Normal file
@@ -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);
|
241
source/blender/bpython/intern/opy_vector.c
Normal file
241
source/blender/bpython/intern/opy_vector.c
Normal file
@@ -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;
|
||||
}
|
63
source/blender/bpython/intern/opy_vector.h
Normal file
63
source/blender/bpython/intern/opy_vector.h
Normal file
@@ -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);
|
||||
|
||||
|
194
source/blender/bpython/intern/opy_window.c
Normal file
194
source/blender/bpython/intern/opy_window.c
Normal file
@@ -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;
|
||||
}
|
Reference in New Issue
Block a user