Merged changes to revision 25007.
The following files were according to the Math Lib reorganization (see the commit log of revision 24464 for more information): source/blender/freestyle/intern/blender_interface/BlenderFileLoader.cpp source/blender/freestyle/intern/blender_interface/BlenderFileLoader.h The file release/scripts/ui/properties_render.py was also updated according the RNA UI API renaming in revision 24795.
This commit is contained in:
@@ -64,6 +64,8 @@
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_text.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
|
||||
#include "BPY_extern.h"
|
||||
|
||||
@@ -75,6 +77,7 @@
|
||||
#include "../generic/Mathutils.h"
|
||||
#include "../generic/Geometry.h"
|
||||
#include "../generic/BGL.h"
|
||||
#include "../generic/IDProp.h"
|
||||
|
||||
|
||||
/* for internal use, when starting and ending python scripts */
|
||||
@@ -177,7 +180,7 @@ static BPy_StructRNA *bpy_context_module= NULL; /* for fast access */
|
||||
static void bpy_init_modules( void )
|
||||
{
|
||||
PyObject *mod;
|
||||
|
||||
|
||||
/* Needs to be first since this dir is needed for future modules */
|
||||
char *modpath= BLI_gethome_folder("scripts/modules", BLI_GETHOME_ALL);
|
||||
if(modpath) {
|
||||
@@ -187,10 +190,18 @@ static void bpy_init_modules( void )
|
||||
Py_DECREF(py_modpath);
|
||||
}
|
||||
|
||||
mod = PyModule_New("bpy");
|
||||
/* stand alone utility modules not related to blender directly */
|
||||
Geometry_Init();
|
||||
Mathutils_Init();
|
||||
BGL_Init();
|
||||
IDProp_Init_Types();
|
||||
Freestyle_Init();
|
||||
|
||||
|
||||
mod = PyModule_New("_bpy");
|
||||
|
||||
/* add the module so we can import it */
|
||||
PyDict_SetItemString(PySys_GetObject("modules"), "bpy", mod);
|
||||
PyDict_SetItemString(PySys_GetObject("modules"), "_bpy", mod);
|
||||
Py_DECREF(mod);
|
||||
|
||||
/* run first, initializes rna types */
|
||||
@@ -202,7 +213,7 @@ static void bpy_init_modules( void )
|
||||
bpy_import_test("bpy_types");
|
||||
/* PyModule_AddObject( mod, "doc", BPY_rna_doc() ); */
|
||||
PyModule_AddObject( mod, "props", BPY_rna_props() );
|
||||
PyModule_AddObject( mod, "__ops__", BPY_operator_module() ); /* ops is now a python module that does the conversion from SOME_OT_foo -> some.foo */
|
||||
PyModule_AddObject( mod, "ops", BPY_operator_module() ); /* ops is now a python module that does the conversion from SOME_OT_foo -> some.foo */
|
||||
PyModule_AddObject( mod, "ui", BPY_ui_module() ); // XXX very experimental, consider this a test, especially PyCObject is not meant to be permanent
|
||||
|
||||
|
||||
@@ -215,17 +226,8 @@ static void bpy_init_modules( void )
|
||||
PyModule_AddObject(mod, "context", (PyObject *)bpy_context_module);
|
||||
}
|
||||
|
||||
/* stand alone utility modules not related to blender directly */
|
||||
Geometry_Init();
|
||||
Mathutils_Init();
|
||||
BGL_Init();
|
||||
Freestyle_Init();
|
||||
|
||||
/* add our own modules dir */
|
||||
{
|
||||
bpy_import_test("bpy_ops"); /* adds its self to bpy.ops */
|
||||
bpy_import_test("bpy_utils"); /* adds its self to bpy.sys */
|
||||
}
|
||||
/* add our own modules dir, this is a python package */
|
||||
bpy_import_test("bpy");
|
||||
}
|
||||
|
||||
void BPY_update_modules( void )
|
||||
@@ -244,34 +246,24 @@ void BPY_update_modules( void )
|
||||
/*****************************************************************************
|
||||
* Description: This function creates a new Python dictionary object.
|
||||
*****************************************************************************/
|
||||
static PyObject *CreateGlobalDictionary( bContext *C )
|
||||
static PyObject *CreateGlobalDictionary( bContext *C, const char *filename )
|
||||
{
|
||||
PyObject *mod;
|
||||
PyObject *item;
|
||||
PyObject *dict = PyDict_New( );
|
||||
PyObject *item = PyUnicode_FromString( "__main__" );
|
||||
PyDict_SetItemString( dict, "__builtins__", PyEval_GetBuiltins( ) );
|
||||
|
||||
item = PyUnicode_FromString( "__main__" );
|
||||
PyDict_SetItemString( dict, "__name__", item );
|
||||
Py_DECREF(item);
|
||||
|
||||
// XXX - put somewhere more logical
|
||||
{
|
||||
PyMethodDef *ml;
|
||||
static PyMethodDef bpy_prop_meths[] = {
|
||||
{"FloatProperty", (PyCFunction)BPy_FloatProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||
{"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||
{"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||
{"StringProperty", (PyCFunction)BPy_StringProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||
{"EnumProperty", (PyCFunction)BPy_EnumProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||
{"PointerProperty", (PyCFunction)BPy_PointerProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||
{"CollectionProperty", (PyCFunction)BPy_CollectionProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
for(ml = bpy_prop_meths; ml->ml_name; ml++) {
|
||||
PyDict_SetItemString( dict, ml->ml_name, PyCFunction_New(ml, NULL));
|
||||
}
|
||||
/* __file__ only for nice UI'ness */
|
||||
if(filename) {
|
||||
PyObject *item = PyUnicode_FromString( filename );
|
||||
PyDict_SetItemString( dict, "__file__", item );
|
||||
Py_DECREF(item);
|
||||
}
|
||||
|
||||
|
||||
/* add bpy to global namespace */
|
||||
mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
|
||||
PyDict_SetItemString( dict, "bpy", mod );
|
||||
@@ -305,6 +297,13 @@ void BPY_start_python_path(void)
|
||||
}
|
||||
|
||||
|
||||
|
||||
void BPY_set_context(bContext *C)
|
||||
{
|
||||
BPy_SetContext(C);
|
||||
}
|
||||
|
||||
/* call BPY_set_context first */
|
||||
void BPY_start_python( int argc, char **argv )
|
||||
{
|
||||
PyThreadState *py_tstate = NULL;
|
||||
@@ -340,11 +339,6 @@ void BPY_start_python( int argc, char **argv )
|
||||
PyObject *d = PyEval_GetBuiltins( );
|
||||
PyDict_SetItemString(d, "reload", item=PyCFunction_New(bpy_reload_meth, NULL)); Py_DECREF(item);
|
||||
PyDict_SetItemString(d, "__import__", item=PyCFunction_New(bpy_import_meth, NULL)); Py_DECREF(item);
|
||||
|
||||
/* a bit nasty but this prevents help() and input() from locking blender
|
||||
* Ideally we could have some way for the console to replace sys.stdin but
|
||||
* python would lock blender while waiting for a return value, not easy :| */
|
||||
PySys_SetObject("stdin", Py_None);
|
||||
}
|
||||
|
||||
pyrna_alloc_types();
|
||||
@@ -399,7 +393,7 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
|
||||
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
py_dict = CreateGlobalDictionary(C);
|
||||
py_dict = CreateGlobalDictionary(C, text?text->id.name+2:fn);
|
||||
|
||||
if (text) {
|
||||
|
||||
@@ -419,24 +413,32 @@ int BPY_run_python_script( bContext *C, const char *fn, struct Text *text, struc
|
||||
py_result = PyEval_EvalCode( text->compiled, py_dict, py_dict );
|
||||
|
||||
} else {
|
||||
#if 0
|
||||
char *pystring;
|
||||
pystring= malloc(strlen(fn) + 32);
|
||||
pystring[0]= '\0';
|
||||
sprintf(pystring, "exec(open(r'%s').read())", fn);
|
||||
py_result = PyRun_String( pystring, Py_file_input, py_dict, py_dict );
|
||||
free(pystring);
|
||||
#else
|
||||
FILE *fp= fopen(fn, "r");
|
||||
if(fp) {
|
||||
#ifdef _WIN32
|
||||
/* Previously we used PyRun_File to run directly the code on a FILE
|
||||
* object, but as written in the Python/C API Ref Manual, chapter 2,
|
||||
* 'FILE structs for different C libraries can be different and
|
||||
* incompatible'.
|
||||
* So now we load the script file data to a buffer */
|
||||
char *pystring;
|
||||
|
||||
fclose(fp);
|
||||
|
||||
pystring= malloc(strlen(fn) + 32);
|
||||
pystring[0]= '\0';
|
||||
sprintf(pystring, "exec(open(r'%s').read())", fn);
|
||||
py_result = PyRun_String( pystring, Py_file_input, py_dict, py_dict );
|
||||
free(pystring);
|
||||
#else
|
||||
py_result = PyRun_File(fp, fn, Py_file_input, py_dict, py_dict);
|
||||
fclose(fp);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
PyErr_Format(PyExc_SystemError, "Python file \"%s\" could not be opened: %s", fn, strerror(errno));
|
||||
py_result= NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!py_result) {
|
||||
@@ -594,117 +596,6 @@ int BPY_run_python_script_space(const char *modulename, const char *func)
|
||||
#include "PIL_time.h"
|
||||
#endif
|
||||
|
||||
/* for use by BPY_run_ui_scripts only */
|
||||
static int bpy_import_module(char *modname, int reload)
|
||||
{
|
||||
PyObject *mod= PyImport_ImportModuleLevel(modname, NULL, NULL, NULL, 0);
|
||||
if (mod) {
|
||||
if (reload) {
|
||||
PyObject *mod_orig= mod;
|
||||
mod= PyImport_ReloadModule(mod);
|
||||
Py_DECREF(mod_orig);
|
||||
}
|
||||
}
|
||||
|
||||
if(mod) {
|
||||
Py_DECREF(mod); /* could be NULL from reloading */
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX this is temporary, need a proper script registration system for 2.5 */
|
||||
void BPY_run_ui_scripts(bContext *C, int reload)
|
||||
{
|
||||
#ifdef TIME_REGISTRATION
|
||||
double time = PIL_check_seconds_timer();
|
||||
#endif
|
||||
DIR *dir;
|
||||
struct dirent *de;
|
||||
char *file_extension;
|
||||
char *dirname;
|
||||
char path[FILE_MAX];
|
||||
char *dirs[] = {"scripts/ui", "scripts/op", "scripts/io", NULL};
|
||||
int path_flags[] = {BLI_GETHOME_LOCAL|BLI_GETHOME_SYSTEM, BLI_GETHOME_USER}; /* SYSTEM / NON-SYSTEM */
|
||||
int a, err, flag_iter;
|
||||
|
||||
PyGILState_STATE gilstate;
|
||||
PyObject *sys_path;
|
||||
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
sys_path= PySys_GetObject("path"); /* borrow */
|
||||
PyList_Insert(sys_path, 0, Py_None); /* place holder, resizes the list */
|
||||
|
||||
/* Scan system scripts first, then local/user */
|
||||
for(flag_iter=0; flag_iter < sizeof(path_flags)/sizeof(int); flag_iter++) {
|
||||
|
||||
for(a=0; dirs[a]; a++) {
|
||||
dirname= BLI_gethome_folder(dirs[a], path_flags[flag_iter]);
|
||||
|
||||
if(!dirname)
|
||||
continue;
|
||||
|
||||
dir = opendir(dirname);
|
||||
|
||||
if(!dir)
|
||||
continue;
|
||||
|
||||
/* set the first dir in the sys.path for fast importing of modules */
|
||||
PyList_SetItem(sys_path, 0, PyUnicode_FromString(dirname)); /* steals the ref */
|
||||
|
||||
while((de = readdir(dir)) != NULL) {
|
||||
/* We could stat the file but easier just to let python
|
||||
* import it and complain if theres a problem */
|
||||
err = 0;
|
||||
|
||||
if (de->d_name[0] == '.') {
|
||||
/* do nothing, probably .svn */
|
||||
}
|
||||
else if ((file_extension = strstr(de->d_name, ".py"))) {
|
||||
/* normal py files? */
|
||||
if(file_extension && file_extension[3] == '\0') {
|
||||
de->d_name[(file_extension - de->d_name)] = '\0';
|
||||
err= bpy_import_module(de->d_name, reload);
|
||||
}
|
||||
}
|
||||
#ifndef __linux__
|
||||
else if( BLI_join_dirfile(path, dirname, de->d_name), S_ISDIR(BLI_exist(path))) {
|
||||
#else
|
||||
else if(de->d_type==DT_DIR) {
|
||||
BLI_join_dirfile(path, dirname, de->d_name);
|
||||
#endif
|
||||
/* support packages */
|
||||
BLI_join_dirfile(path, path, "__init__.py");
|
||||
|
||||
if(BLI_exists(path)) {
|
||||
err= bpy_import_module(de->d_name, reload);
|
||||
}
|
||||
}
|
||||
|
||||
if(err==-1) {
|
||||
BPy_errors_to_report(NULL);
|
||||
fprintf(stderr, "unable to import %s/%s\n", dirname, de->d_name);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
}
|
||||
|
||||
PyList_SetSlice(sys_path, 0, 1, NULL); /* remove the first item */
|
||||
|
||||
bpy_context_clear(C, &gilstate);
|
||||
|
||||
#ifdef TIME_REGISTRATION
|
||||
printf("script time %f\n", (PIL_check_seconds_timer()-time));
|
||||
#endif
|
||||
|
||||
/* reset the timer so as not to take loading into the stats */
|
||||
bpy_timer_count = 0;
|
||||
}
|
||||
|
||||
/* ****************************************** */
|
||||
/* Drivers - PyExpression Evaluation */
|
||||
|
||||
@@ -911,7 +802,7 @@ int BPY_button_eval(bContext *C, char *expr, double *value)
|
||||
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
dict= CreateGlobalDictionary(C);
|
||||
dict= CreateGlobalDictionary(C, NULL);
|
||||
|
||||
/* import some modules: builtins,math*/
|
||||
PyDict_SetItemString(dict, "__builtins__", PyEval_GetBuiltins());
|
||||
@@ -967,9 +858,30 @@ int BPY_button_eval(bContext *C, char *expr, double *value)
|
||||
return error_ret;
|
||||
}
|
||||
|
||||
void BPY_load_user_modules(bContext *C)
|
||||
{
|
||||
PyGILState_STATE gilstate;
|
||||
Text *text;
|
||||
|
||||
bpy_context_set(C, &gilstate);
|
||||
|
||||
int bpy_context_get(bContext *C, const char *member, bContextDataResult *result)
|
||||
for(text=CTX_data_main(C)->text.first; text; text= text->id.next) {
|
||||
if(text->flags & TXT_ISSCRIPT && BLI_testextensie(text->id.name+2, ".py")) {
|
||||
PyObject *module= bpy_text_import(text);
|
||||
|
||||
if (module==NULL) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
}
|
||||
else {
|
||||
Py_DECREF(module);
|
||||
}
|
||||
}
|
||||
}
|
||||
bpy_context_clear(C, &gilstate);
|
||||
}
|
||||
|
||||
int BPY_context_get(bContext *C, const char *member, bContextDataResult *result)
|
||||
{
|
||||
PyObject *pyctx= (PyObject *)CTX_py_dict_get(C);
|
||||
PyObject *item= PyDict_GetItemString(pyctx, member);
|
||||
@@ -1022,8 +934,11 @@ int bpy_context_get(bContext *C, const char *member, bContextDataResult *result)
|
||||
}
|
||||
|
||||
if(done==0) {
|
||||
if (item) printf("Context '%s' not found\n", member);
|
||||
else printf("Context '%s' not a valid type\n", member);
|
||||
if (item) printf("Context '%s' not a valid type\n", member);
|
||||
else printf("Context '%s' not found\n", member);
|
||||
}
|
||||
else if (G.f & G_DEBUG) {
|
||||
printf("Context '%s' found\n", member);
|
||||
}
|
||||
|
||||
return done;
|
||||
|
||||
@@ -57,13 +57,13 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
|
||||
// XXX Todo, work out a better solution for passing on context, could make a tuple from self and pack the name and Context into it...
|
||||
bContext *C = BPy_GetContext();
|
||||
|
||||
if (!PyArg_ParseTuple(args, "sO|O!i:bpy.__ops__.call", &opname, &context_dict, &PyDict_Type, &kw, &context))
|
||||
if (!PyArg_ParseTuple(args, "sO|O!i:_bpy.ops.call", &opname, &context_dict, &PyDict_Type, &kw, &context))
|
||||
return NULL;
|
||||
|
||||
ot= WM_operatortype_find(opname, TRUE);
|
||||
|
||||
if (ot == NULL) {
|
||||
PyErr_Format( PyExc_SystemError, "bpy.__ops__.call: operator \"%s\"could not be found", opname);
|
||||
PyErr_Format( PyExc_SystemError, "_bpy.ops.call: operator \"%s\"could not be found", opname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
|
||||
Py_XINCREF(context_dict); /* so we done loose it */
|
||||
|
||||
if(WM_operator_poll((bContext*)C, ot) == FALSE) {
|
||||
PyErr_SetString( PyExc_SystemError, "bpy.__ops__.call: operator poll() function failed, context is incorrect");
|
||||
PyErr_Format( PyExc_SystemError, "_bpy.ops.call: operator %.200s.poll() function failed, context is incorrect", opname);
|
||||
error_val= -1;
|
||||
}
|
||||
else {
|
||||
@@ -153,18 +153,18 @@ static PyObject *pyop_as_string( PyObject * self, PyObject * args)
|
||||
int all_args = 1;
|
||||
int error_val= 0;
|
||||
|
||||
char *buf;
|
||||
char *buf = NULL;
|
||||
PyObject *pybuf;
|
||||
|
||||
bContext *C = BPy_GetContext();
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s|O!i:bpy.__ops__.as_string", &opname, &PyDict_Type, &kw, &all_args))
|
||||
if (!PyArg_ParseTuple(args, "s|O!i:_bpy.ops.as_string", &opname, &PyDict_Type, &kw, &all_args))
|
||||
return NULL;
|
||||
|
||||
ot= WM_operatortype_find(opname, TRUE);
|
||||
|
||||
if (ot == NULL) {
|
||||
PyErr_Format( PyExc_SystemError, "bpy.__ops__.as_string: operator \"%s\"could not be found", opname);
|
||||
PyErr_Format( PyExc_SystemError, "_bpy.ops.as_string: operator \"%s\"could not be found", opname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -217,12 +217,12 @@ static PyObject *pyop_getrna(PyObject *self, PyObject *value)
|
||||
BPy_StructRNA *pyrna= NULL;
|
||||
|
||||
if(opname==NULL) {
|
||||
PyErr_SetString(PyExc_TypeError, "bpy.__ops__.get_rna() expects a string argument");
|
||||
PyErr_SetString(PyExc_TypeError, "_bpy.ops.get_rna() expects a string argument");
|
||||
return NULL;
|
||||
}
|
||||
ot= WM_operatortype_find(opname, TRUE);
|
||||
if(ot==NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "bpy.__ops__.get_rna(\"%s\") not found", opname);
|
||||
PyErr_Format(PyExc_KeyError, "_bpy.ops.get_rna(\"%s\") not found", opname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -230,7 +230,9 @@ static PyObject *pyop_getrna(PyObject *self, PyObject *value)
|
||||
//RNA_pointer_create(NULL, &RNA_Struct, ot->srna, &ptr);
|
||||
|
||||
/* XXX - should call WM_operator_properties_free */
|
||||
WM_operator_properties_create(&ptr, ot->idname);
|
||||
WM_operator_properties_create_ptr(&ptr, ot);
|
||||
|
||||
|
||||
pyrna= (BPy_StructRNA *)pyrna_struct_CreatePyObject(&ptr);
|
||||
pyrna->freeptr= TRUE;
|
||||
return (PyObject *)pyrna;
|
||||
@@ -245,8 +247,8 @@ PyObject *BPY_operator_module( void )
|
||||
static PyMethodDef pyop_add_meth = {"add", (PyCFunction) PYOP_wrap_add, METH_O, NULL};
|
||||
static PyMethodDef pyop_remove_meth = {"remove", (PyCFunction) PYOP_wrap_remove, METH_O, NULL};
|
||||
|
||||
PyObject *submodule = PyModule_New("bpy.__ops__");
|
||||
PyDict_SetItemString(PySys_GetObject("modules"), "bpy.__ops__", submodule);
|
||||
PyObject *submodule = PyModule_New("_bpy.ops");
|
||||
PyDict_SetItemString(PySys_GetObject("modules"), "_bpy.ops", submodule);
|
||||
|
||||
PyModule_AddObject( submodule, "call", PyCFunction_New(&pyop_call_meth, NULL) );
|
||||
PyModule_AddObject( submodule, "as_string",PyCFunction_New(&pyop_as_string_meth,NULL) );
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
#include "UI_interface.h"
|
||||
#include "ED_screen.h"
|
||||
|
||||
#include "RNA_define.h"
|
||||
@@ -78,10 +79,11 @@ static struct BPY_flag_def pyop_ret_flags[] = {
|
||||
#define PYOP_EXEC 1
|
||||
#define PYOP_INVOKE 2
|
||||
#define PYOP_POLL 3
|
||||
#define PYOP_DRAW 4
|
||||
|
||||
extern void BPY_update_modules( void ); //XXX temp solution
|
||||
|
||||
static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperator *op, wmEvent *event)
|
||||
static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperator *op, wmEvent *event, uiLayout *layout)
|
||||
{
|
||||
PyObject *py_class = ot->pyop_data;
|
||||
PyObject *args;
|
||||
@@ -89,7 +91,6 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperat
|
||||
int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED);
|
||||
PointerRNA ptr_context;
|
||||
PointerRNA ptr_operator;
|
||||
PointerRNA ptr_event;
|
||||
|
||||
PyGILState_STATE gilstate;
|
||||
|
||||
@@ -105,31 +106,18 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperat
|
||||
py_class_instance = PyObject_Call(py_class, args, NULL);
|
||||
Py_DECREF(args);
|
||||
|
||||
if (py_class_instance) { /* Initializing the class worked, now run its invoke function */
|
||||
PyObject *class_dict= PyObject_GetAttrString(py_class_instance, "__dict__");
|
||||
|
||||
/* Assign instance attributes from operator properties */
|
||||
if(op) {
|
||||
const char *arg_name;
|
||||
|
||||
RNA_STRUCT_BEGIN(op->ptr, prop) {
|
||||
arg_name= RNA_property_identifier(prop);
|
||||
|
||||
if (strcmp(arg_name, "rna_type")==0) continue;
|
||||
|
||||
item = pyrna_prop_to_py(op->ptr, prop);
|
||||
PyDict_SetItemString(class_dict, arg_name, item);
|
||||
Py_DECREF(item);
|
||||
}
|
||||
RNA_STRUCT_END;
|
||||
}
|
||||
|
||||
if (py_class_instance==NULL) { /* Initializing the class worked, now run its invoke function */
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
}
|
||||
else {
|
||||
RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context);
|
||||
|
||||
|
||||
if (mode==PYOP_INVOKE) {
|
||||
PointerRNA ptr_event;
|
||||
item= PyObject_GetAttrString(py_class, "invoke");
|
||||
args = PyTuple_New(3);
|
||||
|
||||
|
||||
RNA_pointer_create(NULL, &RNA_Event, event, &ptr_event);
|
||||
|
||||
// PyTuple_SET_ITEM "steals" object reference, it is
|
||||
@@ -148,17 +136,42 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperat
|
||||
args = PyTuple_New(2);
|
||||
PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
|
||||
}
|
||||
else if (mode==PYOP_DRAW) {
|
||||
PointerRNA ptr_layout;
|
||||
item= PyObject_GetAttrString(py_class, "draw");
|
||||
args = PyTuple_New(2);
|
||||
|
||||
RNA_pointer_create(NULL, &RNA_UILayout, layout, &ptr_layout);
|
||||
|
||||
// PyTuple_SET_ITEM "steals" object reference, it is
|
||||
// an object passed shouldn't be DECREF'ed
|
||||
PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
|
||||
#if 0
|
||||
PyTuple_SET_ITEM(args, 2, pyrna_struct_CreatePyObject(&ptr_layout));
|
||||
#else
|
||||
{
|
||||
/* mimic panels */
|
||||
PyObject *py_layout= pyrna_struct_CreatePyObject(&ptr_layout);
|
||||
PyObject *pyname= PyUnicode_FromString("layout");
|
||||
|
||||
if(PyObject_GenericSetAttr(py_class_instance, pyname, py_layout)) {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
}
|
||||
else {
|
||||
Py_DECREF(py_layout);
|
||||
}
|
||||
|
||||
Py_DECREF(pyname);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
PyTuple_SET_ITEM(args, 0, py_class_instance);
|
||||
|
||||
|
||||
ret = PyObject_Call(item, args, NULL);
|
||||
|
||||
|
||||
Py_DECREF(args);
|
||||
Py_DECREF(item);
|
||||
Py_DECREF(class_dict);
|
||||
}
|
||||
else {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
if (ret == NULL) { /* covers py_class_instance failing too */
|
||||
@@ -168,21 +181,18 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperat
|
||||
else {
|
||||
if (mode==PYOP_POLL) {
|
||||
if (PyBool_Check(ret) == 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "Python poll function return value ");
|
||||
if(op)
|
||||
BPy_errors_to_report(op->reports);
|
||||
PyErr_Format(PyExc_ValueError, "Python operator '%s.poll', did not return a bool value", ot->idname);
|
||||
BPy_errors_to_report(op ? op->reports:NULL); /* prints and clears if NULL given */
|
||||
}
|
||||
else {
|
||||
ret_flag= ret==Py_True ? 1:0;
|
||||
}
|
||||
|
||||
} else if(mode==PYOP_DRAW) {
|
||||
/* pass */
|
||||
} else if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) {
|
||||
/* the returned value could not be converted into a flag */
|
||||
if(op) {
|
||||
fprintf(stderr, "error using return value from \"%s\"\n", op->idname); // for some reason the error raised doesnt include file:line... this helps
|
||||
BPy_errors_to_report(op->reports);
|
||||
}
|
||||
|
||||
PyErr_Format(PyExc_ValueError, "Python operator, error using return value from \"%s\"\n", ot->idname);
|
||||
BPy_errors_to_report(op ? op->reports:NULL);
|
||||
ret_flag = OPERATOR_CANCELLED;
|
||||
}
|
||||
/* there is no need to copy the py keyword dict modified by
|
||||
@@ -232,17 +242,22 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperat
|
||||
|
||||
static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
return PYTHON_OT_generic(PYOP_INVOKE, C, op->type, op, event);
|
||||
return PYTHON_OT_generic(PYOP_INVOKE, C, op->type, op, event, NULL);
|
||||
}
|
||||
|
||||
static int PYTHON_OT_execute(bContext *C, wmOperator *op)
|
||||
{
|
||||
return PYTHON_OT_generic(PYOP_EXEC, C, op->type, op, NULL);
|
||||
return PYTHON_OT_generic(PYOP_EXEC, C, op->type, op, NULL, NULL);
|
||||
}
|
||||
|
||||
static int PYTHON_OT_poll(bContext *C, wmOperatorType *ot)
|
||||
{
|
||||
return PYTHON_OT_generic(PYOP_POLL, C, ot, NULL, NULL);
|
||||
return PYTHON_OT_generic(PYOP_POLL, C, ot, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void PYTHON_OT_draw(bContext *C, wmOperator *op, uiLayout *layout)
|
||||
{
|
||||
PYTHON_OT_generic(PYOP_DRAW, C, op->type, op, NULL, layout);
|
||||
}
|
||||
|
||||
void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
|
||||
@@ -279,6 +294,8 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
|
||||
ot->exec= PYTHON_OT_execute;
|
||||
if (PyObject_HasAttrString(py_class, "poll"))
|
||||
ot->pyop_poll= PYTHON_OT_poll;
|
||||
if (PyObject_HasAttrString(py_class, "draw"))
|
||||
ot->ui= PYTHON_OT_draw;
|
||||
|
||||
ot->pyop_data= userdata;
|
||||
|
||||
@@ -308,9 +325,16 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
|
||||
*/
|
||||
item= ((PyTypeObject*)py_class)->tp_dict;
|
||||
if(item) {
|
||||
/* only call this so pyrna_deferred_register_props gives a useful error
|
||||
* WM_operatortype_append_ptr will call RNA_def_struct_identifier
|
||||
* later */
|
||||
RNA_def_struct_identifier(ot->srna, ot->idname);
|
||||
|
||||
if(pyrna_deferred_register_props(ot->srna, item)!=0) {
|
||||
/* failed to register operator props */
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -336,12 +360,17 @@ PyObject *PYOP_wrap_add(PyObject *self, PyObject *py_class)
|
||||
{"execute", 'f', 2, -1, BPY_CLASS_ATTR_OPTIONAL},
|
||||
{"invoke", 'f', 3, -1, BPY_CLASS_ATTR_OPTIONAL},
|
||||
{"poll", 'f', 2, -1, BPY_CLASS_ATTR_OPTIONAL},
|
||||
{"draw", 'f', 2, -1, BPY_CLASS_ATTR_OPTIONAL},
|
||||
{NULL, 0, 0, 0}
|
||||
};
|
||||
|
||||
// in python would be...
|
||||
//PyObject *optype = PyObject_GetAttrString(PyObject_GetAttrString(PyDict_GetItemString(PyEval_GetGlobals(), "bpy"), "types"), "Operator");
|
||||
base_class = PyObject_GetAttrStringArgs(PyDict_GetItemString(PyEval_GetGlobals(), "bpy"), 2, "types", "Operator");
|
||||
|
||||
//PyObject bpy_mod= PyDict_GetItemString(PyEval_GetGlobals(), "bpy");
|
||||
PyObject *bpy_mod= PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0);
|
||||
base_class = PyObject_GetAttrStringArgs(bpy_mod, 2, "types", "Operator");
|
||||
Py_DECREF(bpy_mod);
|
||||
|
||||
if(BPY_class_validate("Operator", py_class, base_class, pyop_class_attr_values, NULL) < 0) {
|
||||
return NULL; /* BPY_class_validate sets the error */
|
||||
@@ -414,6 +443,3 @@ PyObject *PYOP_wrap_remove(PyObject *self, PyObject *value)
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,11 +39,9 @@ extern PyTypeObject pyrna_prop_Type;
|
||||
#define BPy_PropertyRNA_CheckExact(v) (Py_TYPE(v) == &pyrna_prop_Type)
|
||||
|
||||
typedef struct {
|
||||
void * _a;
|
||||
void * _b;
|
||||
PyTypeObject *py_type;
|
||||
} BPy_StructFakeType;
|
||||
|
||||
PyObject_HEAD /* required python macro */
|
||||
PointerRNA ptr;
|
||||
} BPy_DummyPointerRNA;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD /* required python macro */
|
||||
|
||||
@@ -48,7 +48,7 @@ static struct PyMethodDef ui_methods[] = {
|
||||
|
||||
static struct PyModuleDef ui_module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"bpy.ui",
|
||||
"_bpy.ui",
|
||||
"",
|
||||
-1,/* multiple "initialization" just copies the module dict. */
|
||||
ui_methods,
|
||||
|
||||
@@ -162,12 +162,15 @@ void BPY_getFileAndNum(char **filename, int *lineno)
|
||||
|
||||
getframe = PySys_GetObject("_getframe"); // borrowed
|
||||
if (getframe==NULL) {
|
||||
PyErr_Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
frame = PyObject_CallObject(getframe, NULL);
|
||||
if (frame==NULL)
|
||||
if (frame==NULL) {
|
||||
PyErr_Clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (filename) {
|
||||
co_filename= PyObject_GetAttrStringArgs(frame, 1, "f_code", "co_filename");
|
||||
@@ -413,6 +416,7 @@ int BPy_reports_to_error(ReportList *reports)
|
||||
int BPy_errors_to_report(ReportList *reports)
|
||||
{
|
||||
PyObject *pystring;
|
||||
PyObject *pystring_format= NULL; // workaround, see below
|
||||
char *cstring;
|
||||
|
||||
char *filename;
|
||||
@@ -436,14 +440,23 @@ int BPy_errors_to_report(ReportList *reports)
|
||||
}
|
||||
|
||||
BPY_getFileAndNum(&filename, &lineno);
|
||||
if(filename==NULL)
|
||||
filename= "<unknown location>";
|
||||
|
||||
cstring= _PyUnicode_AsString(pystring);
|
||||
|
||||
|
||||
#if 0 // ARG!. workaround for a bug in blenders use of vsnprintf
|
||||
BKE_reportf(reports, RPT_ERROR, "%s\nlocation:%s:%d\n", cstring, filename, lineno);
|
||||
#else
|
||||
pystring_format= PyUnicode_FromFormat("%s\nlocation:%s:%d\n", cstring, filename, lineno);
|
||||
cstring= _PyUnicode_AsString(pystring_format);
|
||||
BKE_report(reports, RPT_ERROR, cstring);
|
||||
#endif
|
||||
|
||||
fprintf(stderr, "%s\nlocation:%s:%d\n", cstring, filename, lineno); // not exactly needed. just for testing
|
||||
|
||||
Py_DECREF(pystring);
|
||||
Py_DECREF(pystring_format); // workaround
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
*/
|
||||
|
||||
/* python, will come back */
|
||||
void BPY_post_start_python() {}
|
||||
//void BPY_run_python_script() {}
|
||||
//void BPY_start_python() {}
|
||||
void BPY_call_importloader() {}
|
||||
|
||||
Reference in New Issue
Block a user