merge with trunk/2.5 at r23876
[[Split portion of a mixed commit.]]
This commit is contained in:
@@ -46,8 +46,6 @@ IF(WITH_FFMPEG)
|
||||
ADD_DEFINITIONS(-DWITH_FFMPEG)
|
||||
ENDIF(WITH_FFMPEG)
|
||||
|
||||
ADD_DEFINITIONS(-DWITH_CCGSUBSURF)
|
||||
|
||||
BLENDERLIB(bf_python "${SRC}" "${INC}")
|
||||
BLENDERLIB(bf_gen_python "${GENSRC}" "${INC}")
|
||||
|
||||
|
||||
@@ -912,7 +912,7 @@ static PyObject *M_Mathutils_LineIntersect( PyObject * self, PyObject * args )
|
||||
PyErr_SetString( PyExc_TypeError, "expected 4 vector types\n" );
|
||||
return NULL;
|
||||
}
|
||||
if( vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec2->size) {
|
||||
if( vec1->size != vec2->size || vec1->size != vec3->size || vec3->size != vec2->size) {
|
||||
PyErr_SetString( PyExc_TypeError,"vectors must be of the same size\n" );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1315,7 +1315,7 @@ static PyObject *column_vector_multiplication(MatrixObject * mat, VectorObject*
|
||||
}
|
||||
vecNew[3] = 1.0f;
|
||||
|
||||
for(x = 0; x < mat->colSize; z++) {
|
||||
for(x = 0; x < mat->colSize; x++) {
|
||||
for(y = 0; y < mat->rowSize; y++) {
|
||||
dot += mat->matrix[y][x] * vecCopy[y];
|
||||
}
|
||||
|
||||
@@ -147,6 +147,17 @@ void bpy_context_clear(bContext *C, PyGILState_STATE *gilstate)
|
||||
}
|
||||
}
|
||||
|
||||
static void bpy_import_test(char *modname)
|
||||
{
|
||||
PyObject *mod= PyImport_ImportModuleLevel(modname, NULL, NULL, NULL, 0);
|
||||
if(mod) {
|
||||
Py_DECREF(mod);
|
||||
}
|
||||
else {
|
||||
PyErr_Print();
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void BPY_free_compiled_text( struct Text *text )
|
||||
{
|
||||
@@ -176,7 +187,21 @@ static void bpy_init_modules( void )
|
||||
PyDict_SetItemString(PySys_GetObject("modules"), "bpy", mod);
|
||||
Py_DECREF(mod);
|
||||
|
||||
|
||||
/* add our own modules dir */
|
||||
{
|
||||
char *modpath= BLI_gethome_folder("scripts/modules", BLI_GETHOME_ALL);
|
||||
|
||||
if(modpath) {
|
||||
PyObject *sys_path= PySys_GetObject("path"); /* borrow */
|
||||
PyObject *py_modpath= PyUnicode_FromString(modpath);
|
||||
PyList_Insert(sys_path, 0, py_modpath); /* add first */
|
||||
Py_DECREF(py_modpath);
|
||||
}
|
||||
|
||||
bpy_import_test("bpy_ops"); /* adds its self to bpy.ops */
|
||||
bpy_import_test("bpy_sys"); /* adds its self to bpy.sys */
|
||||
}
|
||||
|
||||
/* stand alone utility modules not related to blender directly */
|
||||
Geometry_Init();
|
||||
Mathutils_Init();
|
||||
@@ -216,6 +241,9 @@ static PyObject *CreateGlobalDictionary( bContext *C )
|
||||
{"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}
|
||||
};
|
||||
|
||||
@@ -232,26 +260,10 @@ static PyObject *CreateGlobalDictionary( bContext *C )
|
||||
return dict;
|
||||
}
|
||||
|
||||
/* Use this so we can include our own python bundle */
|
||||
#if 0
|
||||
wchar_t* Py_GetPath(void)
|
||||
{
|
||||
int i;
|
||||
static wchar_t py_path[FILE_MAXDIR] = L"";
|
||||
char *dirname= BLI_gethome_folder("python");
|
||||
if(dirname) {
|
||||
i= mbstowcs(py_path, dirname, FILE_MAXDIR);
|
||||
printf("py path %s, %d\n", dirname, i);
|
||||
}
|
||||
return py_path;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* must be called before Py_Initialize */
|
||||
void BPY_start_python_path(void)
|
||||
{
|
||||
char *py_path_bundle= BLI_gethome_folder("python");
|
||||
char *py_path_bundle= BLI_gethome_folder("python", BLI_GETHOME_ALL);
|
||||
|
||||
if(py_path_bundle==NULL)
|
||||
return;
|
||||
@@ -311,6 +323,11 @@ 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();
|
||||
@@ -591,8 +608,9 @@ void BPY_run_ui_scripts(bContext *C, int reload)
|
||||
char *file_extension;
|
||||
char *dirname;
|
||||
char path[FILE_MAX];
|
||||
char *dirs[] = {"ui", "io", NULL};
|
||||
int a, err;
|
||||
char *dirs[] = {"scripts/ui", "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;
|
||||
@@ -602,56 +620,60 @@ void BPY_run_ui_scripts(bContext *C, int reload)
|
||||
sys_path= PySys_GetObject("path"); /* borrow */
|
||||
PyList_Insert(sys_path, 0, Py_None); /* place holder, resizes the list */
|
||||
|
||||
for(a=0; dirs[a]; a++) {
|
||||
dirname= BLI_gethome_folder(dirs[a]);
|
||||
|
||||
if(!dirname)
|
||||
continue;
|
||||
|
||||
dir = opendir(dirname);
|
||||
|
||||
if(!dir)
|
||||
continue;
|
||||
/* Scan system scripts first, then local/user */
|
||||
for(flag_iter=0; flag_iter < sizeof(path_flags)/sizeof(int); flag_iter++) {
|
||||
|
||||
/* set the first dir in the sys.path for fast importing of modules */
|
||||
PyList_SetItem(sys_path, 0, PyUnicode_FromString(dirname)); /* steals the ref */
|
||||
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;
|
||||
|
||||
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;
|
||||
/* 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);
|
||||
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 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);
|
||||
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");
|
||||
/* support packages */
|
||||
BLI_join_dirfile(path, path, "__init__.py");
|
||||
|
||||
if(BLI_exists(path)) {
|
||||
err= bpy_import_module(de->d_name, reload);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if(err==-1) {
|
||||
BPy_errors_to_report(NULL);
|
||||
fprintf(stderr, "unable to import %s/%s\n", dirname, de->d_name);
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
PyList_SetSlice(sys_path, 0, 1, NULL); /* remove the first item */
|
||||
|
||||
@@ -65,7 +65,7 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(ot->poll && (ot->poll(C) == FALSE)) {
|
||||
if(WM_operator_poll((bContext*)C, ot) == FALSE) {
|
||||
PyErr_SetString( PyExc_SystemError, "bpy.__ops__.call: operator poll() function failed, context is incorrect");
|
||||
return NULL;
|
||||
}
|
||||
@@ -89,6 +89,16 @@ static PyObject *pyop_call( PyObject * self, PyObject * args)
|
||||
if(BPy_reports_to_error(reports))
|
||||
error_val = -1;
|
||||
|
||||
/* operator output is nice to have in the terminal/console too */
|
||||
if(reports->list.first) {
|
||||
char *report_str= BKE_reports_string(reports, 0); /* all reports */
|
||||
|
||||
if(report_str) {
|
||||
PySys_WriteStdout("%s\n", report_str);
|
||||
MEM_freeN(report_str);
|
||||
}
|
||||
}
|
||||
|
||||
BKE_reports_clear(reports);
|
||||
if ((reports->flag & RPT_FREE) == 0)
|
||||
{
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#define PYOP_ATTR_IDNAME_BL "__idname_bl__" /* our own name converted into blender syntax, users wont see this */
|
||||
#define PYOP_ATTR_DESCRIPTION "__doc__" /* use pythons docstring */
|
||||
#define PYOP_ATTR_REGISTER "__register__" /* True/False. if this python operator should be registered */
|
||||
#define PYOP_ATTR_UNDO "__undo__" /* True/False. if this python operator should be undone */
|
||||
|
||||
static struct BPY_flag_def pyop_ret_flags[] = {
|
||||
{"RUNNING_MODAL", OPERATOR_RUNNING_MODAL},
|
||||
@@ -81,9 +82,9 @@ static struct BPY_flag_def pyop_ret_flags[] = {
|
||||
|
||||
extern void BPY_update_modules( void ); //XXX temp solution
|
||||
|
||||
static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *event)
|
||||
static int PYTHON_OT_generic(int mode, bContext *C, wmOperatorType *ot, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
PyObject *py_class = op->type->pyop_data;
|
||||
PyObject *py_class = ot->pyop_data;
|
||||
PyObject *args;
|
||||
PyObject *ret= NULL, *py_class_instance, *item= NULL;
|
||||
int ret_flag= (mode==PYOP_POLL ? 0:OPERATOR_CANCELLED);
|
||||
@@ -105,7 +106,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
|
||||
|
||||
|
||||
/* Assign instance attributes from operator properties */
|
||||
{
|
||||
if(op) {
|
||||
const char *arg_name;
|
||||
|
||||
RNA_STRUCT_BEGIN(op->ptr, prop) {
|
||||
@@ -121,10 +122,12 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
|
||||
}
|
||||
|
||||
/* set operator pointer RNA as instance "__operator__" attribute */
|
||||
RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator);
|
||||
py_operator= pyrna_struct_CreatePyObject(&ptr_operator);
|
||||
PyObject_SetAttrString(py_class_instance, "__operator__", py_operator);
|
||||
Py_DECREF(py_operator);
|
||||
if(op) {
|
||||
RNA_pointer_create(NULL, &RNA_Operator, op, &ptr_operator);
|
||||
py_operator= pyrna_struct_CreatePyObject(&ptr_operator);
|
||||
PyObject_SetAttrString(py_class_instance, "__operator__", py_operator);
|
||||
Py_DECREF(py_operator);
|
||||
}
|
||||
|
||||
RNA_pointer_create(NULL, &RNA_Context, C, &ptr_context);
|
||||
|
||||
@@ -148,8 +151,7 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
|
||||
else if (mode==PYOP_POLL) {
|
||||
item= PyObject_GetAttrString(py_class, "poll");
|
||||
args = PyTuple_New(2);
|
||||
//XXX Todo - wrap context in a useful way, None for now.
|
||||
PyTuple_SET_ITEM(args, 1, Py_None);
|
||||
PyTuple_SET_ITEM(args, 1, pyrna_struct_CreatePyObject(&ptr_context));
|
||||
}
|
||||
PyTuple_SET_ITEM(args, 0, py_class_instance);
|
||||
|
||||
@@ -160,21 +162,24 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
|
||||
}
|
||||
|
||||
if (ret == NULL) { /* covers py_class_instance failing too */
|
||||
BPy_errors_to_report(op->reports);
|
||||
if(op)
|
||||
BPy_errors_to_report(op->reports);
|
||||
}
|
||||
else {
|
||||
if (mode==PYOP_POLL) {
|
||||
if (PyBool_Check(ret) == 0) {
|
||||
PyErr_SetString(PyExc_ValueError, "Python poll function return value ");
|
||||
BPy_errors_to_report(op->reports);
|
||||
if(op)
|
||||
BPy_errors_to_report(op->reports);
|
||||
}
|
||||
else {
|
||||
ret_flag= ret==Py_True ? 1:0;
|
||||
}
|
||||
|
||||
} else if (BPY_flag_from_seq(pyop_ret_flags, ret, &ret_flag) == -1) {
|
||||
/* the returned value could not be converted into a flag */
|
||||
BPy_errors_to_report(op->reports);
|
||||
/* the returned value could not be converted into a flag */
|
||||
if(op)
|
||||
BPy_errors_to_report(op->reports);
|
||||
|
||||
ret_flag = OPERATOR_CANCELLED;
|
||||
}
|
||||
@@ -225,19 +230,17 @@ static int PYTHON_OT_generic(int mode, bContext *C, wmOperator *op, wmEvent *eve
|
||||
|
||||
static int PYTHON_OT_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
return PYTHON_OT_generic(PYOP_INVOKE, C, op, event);
|
||||
return PYTHON_OT_generic(PYOP_INVOKE, C, op->type, op, event);
|
||||
}
|
||||
|
||||
static int PYTHON_OT_execute(bContext *C, wmOperator *op)
|
||||
{
|
||||
return PYTHON_OT_generic(PYOP_EXEC, C, op, NULL);
|
||||
return PYTHON_OT_generic(PYOP_EXEC, C, op->type, op, NULL);
|
||||
}
|
||||
|
||||
static int PYTHON_OT_poll(bContext *C)
|
||||
static int PYTHON_OT_poll(bContext *C, wmOperatorType *ot)
|
||||
{
|
||||
// XXX TODO - no way to get the operator type (and therefor class) from the poll function.
|
||||
//return PYTHON_OT_generic(PYOP_POLL, C, NULL, NULL);
|
||||
return 1;
|
||||
return PYTHON_OT_generic(PYOP_POLL, C, ot, NULL, NULL);
|
||||
}
|
||||
|
||||
void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
|
||||
@@ -267,24 +270,38 @@ void PYTHON_OT_wrapper(wmOperatorType *ot, void *userdata)
|
||||
/* api callbacks, detailed checks dont on adding */
|
||||
if (PyObject_HasAttrString(py_class, "invoke"))
|
||||
ot->invoke= PYTHON_OT_invoke;
|
||||
//else
|
||||
// ot->invoke= WM_operator_props_popup; /* could have an option for standard invokes */
|
||||
|
||||
if (PyObject_HasAttrString(py_class, "execute"))
|
||||
ot->exec= PYTHON_OT_execute;
|
||||
if (PyObject_HasAttrString(py_class, "poll"))
|
||||
ot->poll= PYTHON_OT_poll;
|
||||
ot->pyop_poll= PYTHON_OT_poll;
|
||||
|
||||
ot->pyop_data= userdata;
|
||||
|
||||
/* flags */
|
||||
ot->flag= 0;
|
||||
|
||||
item= PyObject_GetAttrString(py_class, PYOP_ATTR_REGISTER);
|
||||
if (item) {
|
||||
ot->flag= PyObject_IsTrue(item)!=0 ? OPTYPE_REGISTER:0;
|
||||
ot->flag |= PyObject_IsTrue(item)!=0 ? OPTYPE_REGISTER:0;
|
||||
Py_DECREF(item);
|
||||
}
|
||||
else {
|
||||
ot->flag= OPTYPE_REGISTER; /* unspesified, leave on for now to help debug */
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
item= PyObject_GetAttrString(py_class, PYOP_ATTR_UNDO);
|
||||
if (item) {
|
||||
ot->flag |= PyObject_IsTrue(item)!=0 ? OPTYPE_UNDO:0;
|
||||
Py_DECREF(item);
|
||||
}
|
||||
else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
props= PyObject_GetAttrString(py_class, PYOP_ATTR_PROP);
|
||||
|
||||
if (props) {
|
||||
|
||||
@@ -345,6 +345,27 @@ static char *pyrna_enum_as_string(PointerRNA *ptr, PropertyRNA *prop)
|
||||
return result;
|
||||
}
|
||||
|
||||
static int pyrna_string_to_enum(PyObject *item, PointerRNA *ptr, PropertyRNA *prop, int *val, const char *error_prefix)
|
||||
{
|
||||
char *param= _PyUnicode_AsString(item);
|
||||
|
||||
if (param==NULL) {
|
||||
char *enum_str= pyrna_enum_as_string(ptr, prop);
|
||||
PyErr_Format(PyExc_TypeError, "%.200s expected a string enum type in (%.200s)", error_prefix, enum_str);
|
||||
MEM_freeN(enum_str);
|
||||
return 0;
|
||||
} else {
|
||||
if (!RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, val)) {
|
||||
char *enum_str= pyrna_enum_as_string(ptr, prop);
|
||||
PyErr_Format(PyExc_TypeError, "%.200s enum \"%.200s\" not found in (%.200s)", error_prefix, param, enum_str);
|
||||
MEM_freeN(enum_str);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
PyObject * pyrna_prop_to_py(PointerRNA *ptr, PropertyRNA *prop)
|
||||
{
|
||||
PyObject *ret;
|
||||
@@ -603,42 +624,52 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
|
||||
}
|
||||
case PROP_ENUM:
|
||||
{
|
||||
char *param = _PyUnicode_AsString(value);
|
||||
|
||||
if (param==NULL) {
|
||||
char *enum_str= pyrna_enum_as_string(ptr, prop);
|
||||
PyErr_Format(PyExc_TypeError, "%.200s expected a string enum type in (%.200s)", error_prefix, enum_str);
|
||||
MEM_freeN(enum_str);
|
||||
return -1;
|
||||
} else {
|
||||
int val;
|
||||
if (RNA_property_enum_value(BPy_GetContext(), ptr, prop, param, &val)) {
|
||||
if(data) *((int*)data)= val;
|
||||
else RNA_property_enum_set(ptr, prop, val);
|
||||
} else {
|
||||
char *enum_str= pyrna_enum_as_string(ptr, prop);
|
||||
PyErr_Format(PyExc_TypeError, "%.200s enum \"%.200s\" not found in (%.200s)", error_prefix, param, enum_str);
|
||||
MEM_freeN(enum_str);
|
||||
int val, i;
|
||||
|
||||
if (PyUnicode_Check(value)) {
|
||||
if (!pyrna_string_to_enum(value, ptr, prop, &val, error_prefix))
|
||||
return -1;
|
||||
}
|
||||
else if (PyTuple_Check(value)) {
|
||||
/* tuple of enum items, concatenate all values with OR */
|
||||
val= 0;
|
||||
for (i= 0; i < PyTuple_Size(value); i++) {
|
||||
int tmpval;
|
||||
|
||||
/* PyTuple_GET_ITEM returns a borrowed reference */
|
||||
if (!pyrna_string_to_enum(PyTuple_GET_ITEM(value, i), ptr, prop, &tmpval, error_prefix))
|
||||
return -1;
|
||||
|
||||
val |= tmpval;
|
||||
}
|
||||
}
|
||||
else {
|
||||
char *enum_str= pyrna_enum_as_string(ptr, prop);
|
||||
PyErr_Format(PyExc_TypeError, "%.200s expected a string enum or a tuple of strings in (%.200s)", error_prefix, enum_str);
|
||||
MEM_freeN(enum_str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(data) *((int*)data)= val;
|
||||
else RNA_property_enum_set(ptr, prop, val);
|
||||
|
||||
break;
|
||||
}
|
||||
case PROP_POINTER:
|
||||
{
|
||||
StructRNA *ptype= RNA_property_pointer_type(ptr, prop);
|
||||
int flag = RNA_property_flag(prop);
|
||||
|
||||
if(!BPy_StructRNA_Check(value) && value != Py_None) {
|
||||
PointerRNA tmp;
|
||||
RNA_pointer_create(NULL, ptype, NULL, &tmp);
|
||||
PyErr_Format(PyExc_TypeError, "%.200s expected a %.200s type", error_prefix, RNA_struct_identifier(tmp.type));
|
||||
PyErr_Format(PyExc_TypeError, "%.200s expected a %.200s type", error_prefix, RNA_struct_identifier(ptype));
|
||||
return -1;
|
||||
} else if((flag & PROP_NEVER_NULL) && value == Py_None) {
|
||||
PyErr_Format(PyExc_TypeError, "property can't be assigned a None value");
|
||||
return -1;
|
||||
} else {
|
||||
BPy_StructRNA *param= (BPy_StructRNA*)value;
|
||||
int raise_error= FALSE;
|
||||
if(data) {
|
||||
int flag = RNA_property_flag(prop);
|
||||
|
||||
if(flag & PROP_RNAPTR) {
|
||||
if(value == Py_None)
|
||||
@@ -731,7 +762,10 @@ int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyObject *v
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Run rna property functions */
|
||||
RNA_property_update(BPy_GetContext(), ptr, prop);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1119,6 +1153,31 @@ static PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA * self, PyObject *ar
|
||||
return PyBool_FromLong( insert_keyframe((ID *)self->ptr.data, NULL, NULL, path, index, cfra, 0));
|
||||
}
|
||||
|
||||
static PyObject *pyrna_struct_is_property_set(BPy_StructRNA * self, PyObject *args)
|
||||
{
|
||||
char *name;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:is_property_set", &name))
|
||||
return NULL;
|
||||
|
||||
return PyBool_FromLong(RNA_property_is_set(&self->ptr, name));
|
||||
}
|
||||
|
||||
static PyObject *pyrna_struct_is_property_hidden(BPy_StructRNA * self, PyObject *args)
|
||||
{
|
||||
PropertyRNA *prop;
|
||||
char *name;
|
||||
int hidden;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:is_property_hidden", &name))
|
||||
return NULL;
|
||||
|
||||
prop= RNA_struct_find_property(&self->ptr, name);
|
||||
hidden= (prop)? (RNA_property_flag(prop) & PROP_HIDDEN): 1;
|
||||
|
||||
return PyBool_FromLong(hidden);
|
||||
}
|
||||
|
||||
|
||||
static PyObject *pyrna_struct_dir(BPy_StructRNA * self)
|
||||
{
|
||||
@@ -1711,6 +1770,8 @@ static struct PyMethodDef pyrna_struct_methods[] = {
|
||||
|
||||
/* maybe this become and ID function */
|
||||
{"keyframe_insert", (PyCFunction)pyrna_struct_keyframe_insert, METH_VARARGS, NULL},
|
||||
{"is_property_set", (PyCFunction)pyrna_struct_is_property_set, METH_VARARGS, NULL},
|
||||
{"is_property_hidden", (PyCFunction)pyrna_struct_is_property_hidden, METH_VARARGS, NULL},
|
||||
|
||||
{"__dir__", (PyCFunction)pyrna_struct_dir, METH_NOARGS, NULL},
|
||||
{NULL, NULL, 0, NULL}
|
||||
@@ -1993,8 +2054,10 @@ static PyObject * pyrna_func_call(PyObject * self, PyObject *args, PyObject *kw)
|
||||
|
||||
/* Check if we gave args that dont exist in the function
|
||||
* printing the error is slow but it should only happen when developing.
|
||||
* the if below is quick, checking if it passed less keyword args then we gave */
|
||||
if(kw && (PyDict_Size(kw) > kw_tot)) {
|
||||
* the if below is quick, checking if it passed less keyword args then we gave.
|
||||
* (Dont overwrite the error if we have one, otherwise can skip important messages and confuse with args)
|
||||
*/
|
||||
if(err == 0 && kw && (PyDict_Size(kw) > kw_tot)) {
|
||||
PyObject *key, *value;
|
||||
Py_ssize_t pos = 0;
|
||||
|
||||
@@ -2252,6 +2315,19 @@ PyTypeObject pyrna_prop_Type = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct PyMethodDef pyrna_struct_subtype_methods[] = {
|
||||
{"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||
{"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||
{"FloatProperty", (PyCFunction)BPy_FloatProperty, 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, ""},
|
||||
|
||||
// {"__get_rna", (PyCFunction)BPy_GetStructRNA, METH_NOARGS, ""},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
|
||||
{
|
||||
PointerRNA ptr;
|
||||
@@ -2277,6 +2353,17 @@ static void pyrna_subtype_set_rna(PyObject *newclass, StructRNA *srna)
|
||||
PyDict_SetItemString(((PyTypeObject *)newclass)->tp_dict, "__rna__", item);
|
||||
Py_DECREF(item);
|
||||
/* done with rna instance */
|
||||
|
||||
/* attach functions into the class
|
||||
* so you can do... bpy.types.Scene.SomeFunction()
|
||||
*/
|
||||
{
|
||||
PyMethodDef *ml;
|
||||
|
||||
for(ml= pyrna_struct_subtype_methods; ml->ml_name; ml++){
|
||||
PyObject_SetAttrString(newclass, ml->ml_name, PyCFunction_New(ml, newclass));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2299,20 +2386,6 @@ PyObject *BPy_GetStructRNA(PyObject *self)
|
||||
}
|
||||
*/
|
||||
|
||||
static struct PyMethodDef pyrna_struct_subtype_methods[] = {
|
||||
{"BoolProperty", (PyCFunction)BPy_BoolProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||
{"IntProperty", (PyCFunction)BPy_IntProperty, METH_VARARGS|METH_KEYWORDS, ""},
|
||||
{"FloatProperty", (PyCFunction)BPy_FloatProperty, 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, ""},
|
||||
|
||||
// {"__get_rna", (PyCFunction)BPy_GetStructRNA, METH_NOARGS, ""},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
||||
PyObject* pyrna_srna_Subtype(StructRNA *srna)
|
||||
{
|
||||
PyObject *newclass = NULL;
|
||||
@@ -2362,18 +2435,6 @@ PyObject* pyrna_srna_Subtype(StructRNA *srna)
|
||||
pyrna_subtype_set_rna(newclass, srna);
|
||||
|
||||
Py_DECREF(newclass); /* let srna own */
|
||||
|
||||
|
||||
/* attach functions into the class
|
||||
* so you can do... bpy.types.Scene.SomeFunction()
|
||||
*/
|
||||
{
|
||||
PyMethodDef *ml;
|
||||
for(ml= pyrna_struct_subtype_methods; ml->ml_name; ml++){
|
||||
PyObject_SetAttrString(newclass, ml->ml_name, PyCFunction_New(ml, newclass));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
/* this should not happen */
|
||||
@@ -2755,7 +2816,7 @@ PyObject *BPy_FloatProperty(PyObject *self, PyObject *args, PyObject *kw)
|
||||
{
|
||||
static char *kwlist[] = {"attr", "name", "description", "min", "max", "soft_min", "soft_max", "default", NULL};
|
||||
char *id, *name="", *description="";
|
||||
float min=FLT_MIN, max=FLT_MAX, soft_min=FLT_MIN, soft_max=FLT_MAX, def=0.0f;
|
||||
float min=-FLT_MAX, max=FLT_MAX, soft_min=-FLT_MAX, soft_max=FLT_MAX, def=0.0f;
|
||||
PropertyRNA *prop;
|
||||
StructRNA *srna;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user