Merged changes in the trunk up to revision 41638.

Conflicts resolved:
doc/python_api/sphinx_doc_gen.py
source/blender/blenkernel/BKE_main.h
source/blender/blenkernel/intern/library.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/editors/include/UI_resources.h
source/blender/editors/interface/resources.c
source/blender/makesdna/DNA_ID.h
source/blender/makesdna/intern/makesdna.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_main.c
source/blender/makesrna/intern/rna_main_api.c
source/blender/makesrna/intern/rna_scene.c
This commit is contained in:
2011-11-08 06:30:02 +00:00
869 changed files with 84392 additions and 13524 deletions

View File

@@ -22,11 +22,11 @@
/** \file blender/python/intern/bpy.c
* \ingroup pythonintern
*
* This file defines the '_bpy' module which is used by python's 'bpy' package
* to access C defined builtin functions.
* A script writer should never directly access this module.
*/
/* This file defines the '_bpy' module which is used by python's 'bpy' package.
* a script writer should never directly access this module */
#define WITH_PYTHON /* for AUD_PyInit.h, possibly others */

View File

@@ -22,6 +22,10 @@
/** \file blender/python/intern/bpy_app.c
* \ingroup pythonintern
*
* This file defines a 'PyStructSequence' accessed via 'bpy.app', mostly
* exposing static applications variables such as version and buildinfo
* however some writable variables have been added such as 'debug' and 'tempdir'
*/

View File

@@ -22,6 +22,10 @@
/** \file blender/python/intern/bpy_app_handlers.c
* \ingroup pythonintern
*
* This file defines a 'PyStructSequence' accessed via 'bpy.app.handlers',
* which exposes various lists that the script author can add callback
* functions into (called via blenders generic BLI_cb api)
*/
#include <Python.h>
@@ -38,15 +42,22 @@ void bpy_app_generic_callback(struct Main *main, struct ID *id, void *arg);
static PyTypeObject BlenderAppCbType;
static PyStructSequence_Field app_cb_info_fields[]= {
{(char *)"frame_change_pre", NULL},
{(char *)"frame_change_post", NULL},
{(char *)"render_pre", NULL},
{(char *)"render_post", NULL},
{(char *)"render_stats", NULL},
{(char *)"load_pre", NULL},
{(char *)"load_post", NULL},
{(char *)"save_pre", NULL},
{(char *)"save_post", NULL},
{(char *)"frame_change_pre", (char *)"Callback list - on frame change for playback and rendering (before)"},
{(char *)"frame_change_post", (char *)"Callback list - on frame change for playback and rendering (after)"},
{(char *)"render_pre", (char *)"Callback list - on render (before)"},
{(char *)"render_post", (char *)"Callback list - on render (after)"},
{(char *)"render_stats", (char *)"Callback list - on printing render statistics"},
{(char *)"load_pre", (char *)"Callback list - on loading a new blend file (before)"},
{(char *)"load_post", (char *)"Callback list - on loading a new blend file (after)"},
{(char *)"save_pre", (char *)"Callback list - on saving a blend file (before)"},
{(char *)"save_post", (char *)"Callback list - on saving a blend file (after)"},
{(char *)"scene_update_pre", (char *)"Callback list - on updating the scenes data (before)"},
{(char *)"scene_update_post", (char *)"Callback list - on updating the scenes data (after)"},
/* sets the permanent tag */
# define APP_CB_OTHER_FIELDS 1
{(char *)"persistent", (char *)"Function decorator for callback functions not to be removed when loading new files"},
{NULL}
};
@@ -63,6 +74,95 @@ static PyStructSequence_Desc app_cb_info_desc= {
#endif
*/
/* --------------------------------------------------------------------------*/
/* permanent tagging code */
#define PERMINENT_CB_ID "_bpy_persistent"
static PyObject *bpy_app_handlers_persistent_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *UNUSED(kwds))
{
PyObject *value;
if(!PyArg_ParseTuple(args, "O:bpy.app.handlers.persistent", &value))
return NULL;
if (PyFunction_Check(value)) {
PyObject **dict_ptr= _PyObject_GetDictPtr(value);
if (dict_ptr == NULL) {
PyErr_SetString(PyExc_ValueError,
"bpy.app.handlers.persistent wasn't able to "
"get the dictionary from the function passed");
return NULL;
}
else {
/* set id */
if (*dict_ptr == NULL) {
*dict_ptr= PyDict_New();
}
PyDict_SetItemString(*dict_ptr, PERMINENT_CB_ID, Py_None);
}
Py_INCREF(value);
return value;
}
else {
PyErr_SetString(PyExc_ValueError,
"bpy.app.handlers.persistent expected a function");
return NULL;
}
}
/* dummy type because decorators can't be PyCFunctions */
static PyTypeObject BPyPersistent_Type = {
#if defined(_MSC_VER) || defined(FREE_WINDOWS)
PyVarObject_HEAD_INIT(NULL, 0)
#else
PyVarObject_HEAD_INIT(&PyType_Type, 0)
#endif
"persistent", /* tp_name */
0, /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
0, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_reserved */
0, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC |
Py_TPFLAGS_BASETYPE, /* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
0, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
bpy_app_handlers_persistent_new, /* tp_new */
0, /* tp_free */
};
static PyObject *py_cb_array[BLI_CB_EVT_TOT]= {NULL};
static PyObject *make_app_cb_info(void)
@@ -81,10 +181,13 @@ static PyObject *make_app_cb_info(void)
}
PyStructSequence_SET_ITEM(app_cb_info, pos, (py_cb_array[pos]= PyList_New(0)));
}
if (app_cb_info_fields[pos].name != NULL) {
if (app_cb_info_fields[pos + APP_CB_OTHER_FIELDS].name != NULL) {
Py_FatalError("invalid callback slots 2");
}
/* custom function */
PyStructSequence_SET_ITEM(app_cb_info, pos++, (PyObject *)&BPyPersistent_Type);
return app_cb_info;
}
@@ -92,6 +195,14 @@ PyObject *BPY_app_handlers_struct(void)
{
PyObject *ret;
#if defined(_MSC_VER) || defined(FREE_WINDOWS)
BPyPersistent_Type.ob_base.ob_base.ob_type= &PyType_Type;
#endif
if (PyType_Ready(&BPyPersistent_Type) < 0) {
BLI_assert(!"error initializing 'bpy.app.handlers.persistent'");
}
PyStructSequence_InitType(&BlenderAppCbType, &app_cb_info_desc);
ret= make_app_cb_info();
@@ -118,12 +229,46 @@ PyObject *BPY_app_handlers_struct(void)
return ret;
}
void BPY_app_handlers_reset(void)
void BPY_app_handlers_reset(const short do_all)
{
int pos= 0;
if (do_all) {
for (pos= 0; pos < BLI_CB_EVT_TOT; pos++) {
PyList_SetSlice(py_cb_array[pos], 0, PY_SSIZE_T_MAX, NULL);
/* clear list */
PyList_SetSlice(py_cb_array[pos], 0, PY_SSIZE_T_MAX, NULL);
}
}
else {
/* save string conversion thrashing */
PyObject *perm_id_str= PyUnicode_FromString(PERMINENT_CB_ID);
for (pos= 0; pos < BLI_CB_EVT_TOT; pos++) {
/* clear only items without PERMINENT_CB_ID */
PyObject *ls= py_cb_array[pos];
Py_ssize_t i;
PyObject *item;
PyObject **dict_ptr;
for(i= PyList_GET_SIZE(ls) - 1; i >= 0; i--) {
if ( (PyFunction_Check((item= PyList_GET_ITEM(ls, i)))) &&
(dict_ptr= _PyObject_GetDictPtr(item)) &&
(*dict_ptr) &&
(PyDict_GetItem(*dict_ptr, perm_id_str) != NULL))
{
/* keep */
}
else {
/* remove */
/* PySequence_DelItem(ls, i); */ /* more obvious buw slower */
PyList_SetSlice(ls, i, i + 1, NULL);
}
}
}
Py_DECREF(perm_id_str);
}
}

View File

@@ -22,6 +22,10 @@
/** \file blender/python/intern/bpy_driver.c
* \ingroup pythonintern
*
* This file defines the 'BPY_driver_exec' to execute python driver expressions,
* called by the animation system, there are also some utility functions
* to deal with the namespace used for driver execution.
*/
/* ****************************************** */

View File

@@ -23,6 +23,10 @@
/** \file blender/python/intern/bpy_interface.c
* \ingroup pythonintern
*
* This file deals with embedding the python interpreter within blender,
* starting and stopping python and exposing blender/python modules so they can
* be accesses from scripts.
*/

View File

@@ -22,6 +22,10 @@
/** \file blender/python/intern/bpy_interface_atexit.c
* \ingroup pythonintern
*
* This file inserts an exit callback into pythons 'atexit' module.
* Without this sys.exit() can crash because blender is not properly closing
* resources.
*/

View File

@@ -22,6 +22,10 @@
/** \file blender/python/intern/bpy_intern_string.c
* \ingroup pythonintern
*
* Store python versions of strings frequently used for python lookups
* to avoid converting, creating the hash and freeing every time as
* PyDict_GetItemString and PyObject_GetAttrString do.
*/
#include <Python.h>

View File

@@ -22,6 +22,13 @@
/** \file blender/python/intern/bpy_library.c
* \ingroup pythonintern
*
* This file exposed blend file library appending/linking to python, typically
* this would be done via RNA api but in this case a hand written python api
* allows us to use pythons context manager (__enter__ and __exit__).
*
* Everything here is exposed via bpy.data.libraries.load(...) which returns
* a context manager.
*/
/* nifty feature. swap out strings for RNA data */
@@ -71,8 +78,8 @@ static PyObject *bpy_lib_dir(BPy_Library *self);
static PyMethodDef bpy_lib_methods[]= {
{"__enter__", (PyCFunction)bpy_lib_enter, METH_NOARGS},
{"__exit__", (PyCFunction)bpy_lib_exit, METH_VARARGS},
{"__dir__", (PyCFunction)bpy_lib_dir, METH_NOARGS},
{"__exit__", (PyCFunction)bpy_lib_exit, METH_VARARGS},
{"__dir__", (PyCFunction)bpy_lib_dir, METH_NOARGS},
{NULL} /* sentinel */
};
@@ -283,7 +290,7 @@ static void bpy_lib_exit_warn_idname(BPy_Library *self, const char *name_plural,
PyObject *exc, *val, *tb;
PyErr_Fetch(&exc, &val, &tb);
if (PyErr_WarnFormat(PyExc_UserWarning, 1,
"load: '%s' does not contain %s[\"%s\"]",
"load: '%s' does not contain %s[\"%s\"]",
self->abspath, name_plural, idname)) {
/* Spurious errors can appear at shutdown */
if (PyErr_ExceptionMatches(PyExc_Warning)) {
@@ -298,7 +305,7 @@ static void bpy_lib_exit_warn_type(BPy_Library *self, PyObject *item)
PyObject *exc, *val, *tb;
PyErr_Fetch(&exc, &val, &tb);
if (PyErr_WarnFormat(PyExc_UserWarning, 1,
"load: '%s' expected a string type, not a %.200s",
"load: '%s' expected a string type, not a %.200s",
self->abspath, Py_TYPE(item)->tp_name)) {
/* Spurious errors can appear at shutdown */
if (PyErr_ExceptionMatches(PyExc_Warning)) {

View File

@@ -1,6 +1,4 @@
/*
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -24,6 +22,13 @@
/** \file blender/python/intern/bpy_operator.c
* \ingroup pythonintern
*
* This file defines '_bpy.ops', an internal python module which gives python
* the ability to inspect and call both C and Python defined operators.
*
* \note
* This module is exposed to the user via 'release/scripts/modules/bpy/ops.py'
* which fakes exposing operators as modules/functions using its own classes.
*/
@@ -380,7 +385,7 @@ static PyObject *pyop_getrna(PyObject *UNUSED(self), PyObject *value)
{
wmOperatorType *ot;
PointerRNA ptr;
char *opname= _PyUnicode_AsString(value);
const char *opname= _PyUnicode_AsString(value);
BPy_StructRNA *pyrna= NULL;
if (opname==NULL) {
@@ -413,7 +418,7 @@ static PyObject *pyop_getinstance(PyObject *UNUSED(self), PyObject *value)
wmOperatorType *ot;
wmOperator *op;
PointerRNA ptr;
char *opname= _PyUnicode_AsString(value);
const char *opname= _PyUnicode_AsString(value);
BPy_StructRNA *pyrna= NULL;
if (opname==NULL) {

View File

@@ -22,6 +22,11 @@
/** \file blender/python/intern/bpy_operator_wrap.c
* \ingroup pythonintern
*
* This file is so python can define operators that C can call into.
* The generic callback functions for python operators are defines in
* 'rna_wm.c', some calling into functions here to do python specific
* functionality.
*/

View File

@@ -22,6 +22,10 @@
/** \file blender/python/intern/bpy_props.c
* \ingroup pythonintern
*
* This file defines 'bpy.props' module used so scripts can define their own
* rna properties for use with python operators or adding new properties to
* existing blender types.
*/
@@ -254,7 +258,7 @@ static int bpy_prop_callback_assign(struct PropertyRNA *prop, PyObject *update_c
{
/* assume this is already checked for type and arg length */
if (update_cb) {
PyObject **py_data= MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, "bpy_prop_callback_assign");
PyObject **py_data= MEM_callocN(sizeof(PyObject *) * BPY_DATA_CB_SLOT_SIZE, __func__);
RNA_def_property_update_runtime(prop, (void *)bpy_prop_update_cb);
py_data[BPY_DATA_CB_SLOT_UPDATE]= update_cb;
RNA_def_py_data(prop, py_data);
@@ -279,52 +283,60 @@ static int py_long_as_int(PyObject *py_long, int *r_int)
/* this define runs at the start of each function and deals with
* returning a deferred property (to be registered later) */
#define BPY_PROPDEF_HEAD(_func) \
if (PyTuple_GET_SIZE(args) == 1) { \
PyObject *ret; \
self= PyTuple_GET_ITEM(args, 0); \
args= PyTuple_New(0); \
ret= BPy_##_func(self, args, kw); \
Py_DECREF(args); \
return ret; \
} \
else if (PyTuple_GET_SIZE(args) > 1) { \
PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \
return NULL; \
} \
srna= srna_from_self(self, #_func"(...):"); \
if (srna==NULL) { \
if (PyErr_Occurred()) \
return NULL; \
return bpy_prop_deferred_return((void *)pymeth_##_func, kw); \
} \
#define BPY_PROPDEF_HEAD(_func) \
if (PyTuple_GET_SIZE(args) == 1) { \
PyObject *ret; \
self= PyTuple_GET_ITEM(args, 0); \
args= PyTuple_New(0); \
ret= BPy_##_func(self, args, kw); \
Py_DECREF(args); \
return ret; \
} \
else if (PyTuple_GET_SIZE(args) > 1) { \
PyErr_SetString(PyExc_ValueError, "all args must be keywords"); \
return NULL; \
} \
srna= srna_from_self(self, #_func"(...):"); \
if (srna==NULL) { \
if (PyErr_Occurred()) \
return NULL; \
return bpy_prop_deferred_return((void *)pymeth_##_func, kw); \
} \
/* terse macros for error checks shared between all funcs cant use function
* calls because of static strins passed to pyrna_set_to_enum_bitfield */
#define BPY_PROPDEF_CHECK(_func, _property_flag_items) \
if (id_len >= MAX_IDPROP_NAME) { \
PyErr_Format(PyExc_TypeError, \
#_func"(): '%.200s' too long, max length is %d", \
id, MAX_IDPROP_NAME-1); \
return NULL; \
} \
if (RNA_def_property_free_identifier(srna, id) == -1) { \
PyErr_Format(PyExc_TypeError, \
#_func"(): '%s' is defined as a non-dynamic type", \
id); \
return NULL; \
} \
if (pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, pyopts, &opts, #_func"(options={...}):")) \
return NULL; \
#define BPY_PROPDEF_CHECK(_func, _property_flag_items) \
if (id_len >= MAX_IDPROP_NAME) { \
PyErr_Format(PyExc_TypeError, \
#_func"(): '%.200s' too long, max length is %d", \
id, MAX_IDPROP_NAME-1); \
return NULL; \
} \
if (RNA_def_property_free_identifier(srna, id) == -1) { \
PyErr_Format(PyExc_TypeError, \
#_func"(): '%s' is defined as a non-dynamic type", \
id); \
return NULL; \
} \
if (pyopts && pyrna_set_to_enum_bitfield(_property_flag_items, \
pyopts, \
&opts, \
#_func"(options={...}):")) \
{ \
return NULL; \
} \
#define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \
BPY_PROPDEF_CHECK(_func, _property_flag_items) \
if (pysubtype && RNA_enum_value_from_id(_subtype, pysubtype, &subtype)==0) { \
PyErr_Format(PyExc_TypeError, \
#_func"(subtype='%s'): invalid subtype", \
pysubtype); \
return NULL; \
} \
#define BPY_PROPDEF_SUBTYPE_CHECK(_func, _property_flag_items, _subtype) \
BPY_PROPDEF_CHECK(_func, _property_flag_items) \
if (pysubtype && RNA_enum_value_from_id(_subtype, \
pysubtype, \
&subtype)==0) \
{ \
PyErr_Format(PyExc_TypeError, \
#_func"(subtype='%s'): invalid subtype", \
pysubtype); \
return NULL; \
} \
#define BPY_PROPDEF_NAME_DOC \
@@ -1211,7 +1223,7 @@ static StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix
if (!srna) {
if (PyErr_Occurred()) {
PyObject *msg= PyC_ExceptionBuffer();
char *msg_char= _PyUnicode_AsString(msg);
const char *msg_char= _PyUnicode_AsString(msg);
PyErr_Format(PyExc_TypeError,
"%.200s expected an RNA type derived from PropertyGroup, failed with: %s",
error_prefix, msg_char);

View File

@@ -22,9 +22,14 @@
/** \file blender/python/intern/bpy_rna.c
* \ingroup pythonintern
*
* This file is the main interface between python and blenders data api (RNA),
* exposing RNA to python so blender data can be accessed in a python like way.
*
* The two main types are 'BPy_StructRNA' and 'BPy_PropertyRNA' - the base
* classes for most of the data python accesses in blender.
*/
#include <Python.h>
#include <stddef.h>
@@ -82,10 +87,10 @@
static PyObject* pyrna_struct_Subtype(PointerRNA *ptr);
static PyObject *pyrna_prop_collection_values(BPy_PropertyRNA *self);
#define BPY_DOC_ID_PROP_TYPE_NOTE \
" .. note::\n" \
"\n" \
" Only :class:`bpy.types.ID`, :class:`bpy.types.Bone` and \n" \
#define BPY_DOC_ID_PROP_TYPE_NOTE \
" .. note::\n" \
"\n" \
" Only :class:`bpy.types.ID`, :class:`bpy.types.Bone` and \n" \
" :class:`bpy.types.PoseBone` classes support custom properties.\n"
@@ -6404,17 +6409,19 @@ static int bpy_class_validate(PointerRNA *dummyptr, void *py_data, int *have_fun
if (item==NULL) {
/* Sneaky workaround to use the class name as the bl_idname */
#define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \
if (strcmp(identifier, rna_attr) == 0) { \
item= PyObject_GetAttrString(py_class, py_attr); \
if (item && item != Py_None) { \
if (pyrna_py_to_prop(dummyptr, prop, NULL, item, "validating class:") != 0) { \
Py_DECREF(item); \
return -1; \
} \
} \
Py_XDECREF(item); \
} \
#define BPY_REPLACEMENT_STRING(rna_attr, py_attr) \
if (strcmp(identifier, rna_attr) == 0) { \
item= PyObject_GetAttrString(py_class, py_attr); \
if (item && item != Py_None) { \
if (pyrna_py_to_prop(dummyptr, prop, NULL, \
item, "validating class:") != 0) \
{ \
Py_DECREF(item); \
return -1; \
} \
} \
Py_XDECREF(item); \
} \
BPY_REPLACEMENT_STRING("bl_idname", "__name__");
@@ -6468,7 +6475,9 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
const int is_operator= RNA_struct_is_a(ptr->type, &RNA_Operator);
const char *func_id= RNA_function_identifier(func);
/* testing, for correctness, not operator and not draw function */
const short is_readonly= strstr("draw", func_id) || /*strstr("render", func_id) ||*/ !is_operator;
const short is_readonly= ((strncmp("draw", func_id, 4) ==0) || /* draw or draw_header */
/*strstr("render", func_id) ||*/
!is_operator);
#endif
py_class= RNA_struct_py_type_get(ptr->type);

View File

@@ -22,6 +22,8 @@
/** \file blender/python/intern/bpy_rna_anim.c
* \ingroup pythonintern
*
* This file defines the animation related methods used in bpy_rna.c
*/
#include <Python.h>

View File

@@ -15,13 +15,15 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Contributor(s): Arystanbek Dyussenov
* Contributor(s): Arystanbek Dyussenov, Campbell Barton
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/intern/bpy_rna_array.c
* \ingroup pythonintern
*
* This file deals with array access for 'BPy_PropertyArrayRNA' from bpy_rna.c
*/
#include <Python.h>

View File

@@ -22,6 +22,9 @@
/** \file blender/python/intern/bpy_rna_callback.c
* \ingroup pythonintern
*
* This file currently exposes callbacks for interface regions but may be
* extended later.
*/

View File

@@ -20,6 +20,9 @@
/** \file blender/python/intern/bpy_traceback.c
* \ingroup pythonintern
*
* This file contains utility functions for getting data from a python stack
* trace.
*/

View File

@@ -22,9 +22,11 @@
/** \file blender/python/intern/bpy_util.c
* \ingroup pythonintern
*
* This file contains blender/python utility functions for the api's internal
* use (unrelated to 'bpy.utils')
*/
#include <Python.h>
#include "bpy_util.h"

View File

@@ -27,6 +27,9 @@
/** \file blender/python/intern/gpu.c
* \ingroup pythonintern
*
* This file defines the 'gpu' module, used to get GLSL shader code and data
* from blender materials.
*/
/* python redefines */