diff options
Diffstat (limited to 'source/blender/python')
-rw-r--r-- | source/blender/python/generic/noise_py_api.c | 20 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_interface.c | 25 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 173 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_util.h | 1 |
4 files changed, 162 insertions, 57 deletions
diff --git a/source/blender/python/generic/noise_py_api.c b/source/blender/python/generic/noise_py_api.c index f5761f713a6..7be0998c0a1 100644 --- a/source/blender/python/generic/noise_py_api.c +++ b/source/blender/python/generic/noise_py_api.c @@ -210,8 +210,8 @@ static void randuvec(float v[3]) if((r = 1.f - v[2] * v[2]) > 0.f) { float a = (float)(6.283185307f * frand()); r = (float)sqrt(r); - v[0] = (float)(r * cos(a)); - v[1] = (float)(r * sin(a)); + v[0] = (float)(r * cosf(a)); + v[1] = (float)(r * sinf(a)); } else { v[2] = 1.f; @@ -254,7 +254,7 @@ static PyObject *Noise_noise(PyObject *UNUSED(self), PyObject *args) if(!PyArg_ParseTuple(args, "(fff)|i:noise", &x, &y, &z, &nb)) return NULL; - return PyFloat_FromDouble((2.0 * BLI_gNoise(1.0, x, y, z, 0, nb) - 1.0)); + return PyFloat_FromDouble((2.0f * BLI_gNoise(1.0f, x, y, z, 0, nb) - 1.0f)); } /*-------------------------------------------------------------------------*/ @@ -264,11 +264,11 @@ static PyObject *Noise_noise(PyObject *UNUSED(self), PyObject *args) static void noise_vector(float x, float y, float z, int nb, float v[3]) { /* Simply evaluate noise at 3 different positions */ - v[0] = (float)(2.0 * BLI_gNoise(1.f, x + 9.321f, y - 1.531f, z - 7.951f, 0, - nb) - 1.0); - v[1] = (float)(2.0 * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0); - v[2] = (float)(2.0 * BLI_gNoise(1.f, x + 6.327f, y + 0.1671f, z - 2.672f, 0, - nb) - 1.0); + v[0]= (float)(2.0f * BLI_gNoise(1.f, x + 9.321f, y - 1.531f, z - 7.951f, 0, + nb) - 1.0f); + v[1]= (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f); + v[2]= (float)(2.0f * BLI_gNoise(1.f, x + 6.327f, y + 0.1671f, z - 2.672f, 0, + nb) - 1.0f); } static PyObject *Noise_vector(PyObject *UNUSED(self), PyObject *args) @@ -291,7 +291,7 @@ static float turb(float x, float y, float z, int oct, int hard, int nb, float amp, out, t; int i; amp = 1.f; - out = (float)(2.0 * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0); + out = (float)(2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f); if(hard) out = (float)fabs(out); for(i = 1; i < oct; i++) { @@ -299,7 +299,7 @@ static float turb(float x, float y, float z, int oct, int hard, int nb, x *= freqscale; y *= freqscale; z *= freqscale; - t = (float)(amp * (2.0 * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0)); + t = (float)(amp * (2.0f * BLI_gNoise(1.f, x, y, z, 0, nb) - 1.0f)); if(hard) t = (float)fabs(t); out += t; diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index ea76c4bb377..d5615f5ab2d 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -87,6 +87,14 @@ static double bpy_timer_run; /* time for each python script run */ static double bpy_timer_run_tot; /* accumulate python runs */ #endif +/* use for updating while a python script runs - in case of file load */ +void bpy_context_update(bContext *C) +{ + BPy_SetContext(C); + bpy_import_main_set(CTX_data_main(C)); + BPY_modules_update(C); /* can give really bad results if this isnt here */ +} + void bpy_context_set(bContext *C, PyGILState_STATE *gilstate) { py_call_level++; @@ -95,16 +103,7 @@ void bpy_context_set(bContext *C, PyGILState_STATE *gilstate) *gilstate= PyGILState_Ensure(); if(py_call_level==1) { - - if(C) { // XXX - should always be true. - BPy_SetContext(C); - bpy_import_main_set(CTX_data_main(C)); - } - else { - fprintf(stderr, "ERROR: Python context called with a NULL Context. this should not happen!\n"); - } - - BPY_modules_update(C); /* can give really bad results if this isnt here */ + bpy_context_update(C); #ifdef TIME_PY_RUN if(bpy_timer_count==0) { @@ -575,6 +574,12 @@ void BPY_modules_load_user(bContext *C) if(bmain==NULL) return; + /* update pointers since this can run from a nested script + * on file load */ + if(py_call_level) { + bpy_context_update(C); + } + bpy_context_set(C, &gilstate); for(text=CTX_data_main(C)->text.first; text; text= text->id.next) { diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index ba8145c2773..72553872057 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -84,7 +84,9 @@ int pyrna_struct_validity_check(BPy_StructRNA *pysrna) { if(pysrna->ptr.type) return 0; - PyErr_Format(PyExc_ReferenceError, "StructRNA of type %.200s has been removed", Py_TYPE(pysrna)->tp_name); + PyErr_Format(PyExc_ReferenceError, + "StructRNA of type %.200s has been removed", + Py_TYPE(pysrna)->tp_name); return -1; } @@ -790,43 +792,62 @@ static PyObject *pyrna_struct_str(BPy_StructRNA *self) const char *name; if(!PYRNA_STRUCT_IS_VALID(self)) { - return PyUnicode_FromFormat("<bpy_struct, %.200s dead>", Py_TYPE(self)->tp_name); + return PyUnicode_FromFormat("<bpy_struct, %.200s dead>", + Py_TYPE(self)->tp_name); } /* print name if available */ name= RNA_struct_name_get_alloc(&self->ptr, NULL, FALSE); if(name) { - ret= PyUnicode_FromFormat("<bpy_struct, %.200s(\"%.200s\")>", RNA_struct_identifier(self->ptr.type), name); + ret= PyUnicode_FromFormat("<bpy_struct, %.200s(\"%.200s\")>", + RNA_struct_identifier(self->ptr.type), + name); MEM_freeN((void *)name); return ret; } - return PyUnicode_FromFormat("<bpy_struct, %.200s at %p>", RNA_struct_identifier(self->ptr.type), self->ptr.data); + return PyUnicode_FromFormat("<bpy_struct, %.200s at %p>", + RNA_struct_identifier(self->ptr.type), + self->ptr.data); } static PyObject *pyrna_struct_repr(BPy_StructRNA *self) { ID *id= self->ptr.id.data; + PyObject *tmp_str; + PyObject *ret; + if(id == NULL || !PYRNA_STRUCT_IS_VALID(self)) return pyrna_struct_str(self); /* fallback */ + tmp_str= PyUnicode_FromString(id->name+2); + if(RNA_struct_is_ID(self->ptr.type)) { - return PyUnicode_FromFormat("bpy.data.%s[\"%s\"]", BKE_idcode_to_name_plural(GS(id->name)), id->name+2); + ret= PyUnicode_FromFormat("bpy.data.%s[%R]", + BKE_idcode_to_name_plural(GS(id->name)), + tmp_str); } else { - PyObject *ret; const char *path; path= RNA_path_from_ID_to_struct(&self->ptr); if(path) { - ret= PyUnicode_FromFormat("bpy.data.%s[\"%s\"].%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, path); + ret= PyUnicode_FromFormat("bpy.data.%s[%R].%s", + BKE_idcode_to_name_plural(GS(id->name)), + tmp_str, + path); MEM_freeN((void *)path); } else { /* cant find, print something sane */ - ret= PyUnicode_FromFormat("bpy.data.%s[\"%s\"]...%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, RNA_struct_identifier(self->ptr.type)); + ret= PyUnicode_FromFormat("bpy.data.%s[%R]...%s", + BKE_idcode_to_name_plural(GS(id->name)), + tmp_str, + RNA_struct_identifier(self->ptr.type)); } - - return ret; } + + Py_DECREF(tmp_str); + + return ret; } static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) @@ -870,7 +891,11 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) name= RNA_struct_name_get_alloc(&ptr, NULL, FALSE); if(name) { - ret= PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s(\"%.200s\")>", type_fmt, RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop), name); + ret= PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s(\"%.200s\")>", + type_fmt, + RNA_struct_identifier(self->ptr.type), + RNA_property_identifier(self->prop), + name); MEM_freeN((void *)name); return ret; } @@ -878,40 +903,59 @@ static PyObject *pyrna_prop_str(BPy_PropertyRNA *self) if(RNA_property_type(self->prop) == PROP_COLLECTION) { PointerRNA r_ptr; if(RNA_property_collection_type_get(&self->ptr, self->prop, &r_ptr)) { - return PyUnicode_FromFormat("<bpy_%.200s, %.200s>", type_fmt, RNA_struct_identifier(r_ptr.type)); + return PyUnicode_FromFormat("<bpy_%.200s, %.200s>", + type_fmt, + RNA_struct_identifier(r_ptr.type)); } } - return PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s>", type_fmt, RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop)); + return PyUnicode_FromFormat("<bpy_%.200s, %.200s.%.200s>", + type_fmt, + RNA_struct_identifier(self->ptr.type), + RNA_property_identifier(self->prop)); } static PyObject *pyrna_prop_repr(BPy_PropertyRNA *self) { - ID *id; + ID *id= self->ptr.id.data; + PyObject *tmp_str; PyObject *ret; const char *path; PYRNA_PROP_CHECK_OBJ(self) - if((id= self->ptr.id.data) == NULL) + if(id == NULL) return pyrna_prop_str(self); /* fallback */ + tmp_str= PyUnicode_FromString(id->name+2); + path= RNA_path_from_ID_to_property(&self->ptr, self->prop); if(path) { - ret= PyUnicode_FromFormat("bpy.data.%s[\"%s\"].%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, path); + ret= PyUnicode_FromFormat("bpy.data.%s[%R].%s", + BKE_idcode_to_name_plural(GS(id->name)), + tmp_str, + path); MEM_freeN((void *)path); } else { /* cant find, print something sane */ - ret= PyUnicode_FromFormat("bpy.data.%s[\"%s\"]...%s", BKE_idcode_to_name_plural(GS(id->name)), id->name+2, RNA_property_identifier(self->prop)); + ret= PyUnicode_FromFormat("bpy.data.%s[%R]...%s", + BKE_idcode_to_name_plural(GS(id->name)), + tmp_str, + RNA_property_identifier(self->prop)); } + Py_DECREF(tmp_str); + return ret; } static PyObject *pyrna_func_repr(BPy_FunctionRNA *self) { - return PyUnicode_FromFormat("<%.200s %.200s.%.200s()>", Py_TYPE(self)->tp_name, RNA_struct_identifier(self->ptr.type), RNA_function_identifier(self->func)); + return PyUnicode_FromFormat("<%.200s %.200s.%.200s()>", + Py_TYPE(self)->tp_name, + RNA_struct_identifier(self->ptr.type), + RNA_function_identifier(self->func)); } @@ -2995,7 +3039,9 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) else if (self->ptr.type == &RNA_Context) { bContext *C= self->ptr.data; if(C==NULL) { - PyErr_Format(PyExc_AttributeError, "bpy_struct: Context is 'NULL', can't get \"%.200s\" from context", name); + PyErr_Format(PyExc_AttributeError, + "bpy_struct: Context is 'NULL', can't get \"%.200s\" from context", + name); ret= NULL; } else { @@ -3054,7 +3100,9 @@ static PyObject *pyrna_struct_getattro(BPy_StructRNA *self, PyObject *pyname) } else { #if 0 - PyErr_Format(PyExc_AttributeError, "bpy_struct: attribute \"%.200s\" not found", name); + PyErr_Format(PyExc_AttributeError, + "bpy_struct: attribute \"%.200s\" not found", + name); ret= NULL; #endif /* Include this incase this instance is a subtype of a python class @@ -3170,7 +3218,9 @@ static int pyrna_struct_meta_idprop_setattro(PyObject *cls, PyObject *attr, PyOb const char *attr_str= _PyUnicode_AsString(attr); int ret= RNA_def_property_free_identifier(srna, attr_str); if (ret == -1) { - PyErr_Format(PyExc_TypeError, "struct_meta_idprop.detattr(): '%s' not a dynamic property", attr_str); + PyErr_Format(PyExc_TypeError, + "struct_meta_idprop.detattr(): '%s' not a dynamic property", + attr_str); return -1; } } @@ -3208,7 +3258,9 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject /* code just raises correct error, context prop's cant be set, unless its apart of the py class */ bContext *C= self->ptr.data; if(C==NULL) { - PyErr_Format(PyExc_AttributeError, "bpy_struct: Context is 'NULL', can't set \"%.200s\" from context", name); + PyErr_Format(PyExc_AttributeError, + "bpy_struct: Context is 'NULL', can't set \"%.200s\" from context", + name); return -1; } else { @@ -3219,7 +3271,9 @@ static int pyrna_struct_setattro(BPy_StructRNA *self, PyObject *pyname, PyObject int done= CTX_data_get(C, name, &newptr, &newlb, &newtype); if(done==1) { - PyErr_Format(PyExc_AttributeError, "bpy_struct: Context property \"%.200s\" is read-only", name); + PyErr_Format(PyExc_AttributeError, + "bpy_struct: Context property \"%.200s\" is read-only", + name); BLI_freelistN(&newlb); return -1; } @@ -3363,7 +3417,9 @@ static int pyrna_prop_collection_setattro(BPy_PropertyRNA *self, PyObject *pynam } } - PyErr_Format(PyExc_AttributeError, "bpy_prop_collection: attribute \"%.200s\" not found", name); + PyErr_Format(PyExc_AttributeError, + "bpy_prop_collection: attribute \"%.200s\" not found", + name); return -1; } @@ -4048,11 +4104,14 @@ static PyObject *pyrna_struct_new(PyTypeObject *type, PyObject *args, PyObject * } /* error, invalid type given */ - PyErr_Format(PyExc_TypeError, "bpy_struct.__new__(type): type '%.200s' is not a subtype of bpy_struct", type->tp_name); + PyErr_Format(PyExc_TypeError, + "bpy_struct.__new__(type): type '%.200s' is not a subtype of bpy_struct", + type->tp_name); return NULL; } else { - PyErr_Format(PyExc_TypeError, "bpy_struct.__new__(type): expected a single argument"); + PyErr_Format(PyExc_TypeError, + "bpy_struct.__new__(type): expected a single argument"); return NULL; } } @@ -4077,7 +4136,9 @@ static PyObject *pyrna_prop_new(PyTypeObject *type, PyObject *args, PyObject *UN return (PyObject *)ret; } else { - PyErr_Format(PyExc_TypeError, "bpy_prop.__new__(type): type '%.200s' is not a subtype of bpy_prop", type->tp_name); + PyErr_Format(PyExc_TypeError, + "bpy_prop.__new__(type): type '%.200s' is not a subtype of bpy_prop", + type->tp_name); return NULL; } } @@ -4139,7 +4200,9 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat } break; default: - PyErr_Format(PyExc_TypeError, "RNA Error: unknown array type \"%d\" (pyrna_param_to_py)", type); + PyErr_Format(PyExc_TypeError, + "RNA Error: unknown array type \"%d\" (pyrna_param_to_py)", + type); ret= NULL; break; } @@ -4237,7 +4300,9 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat break; } default: - PyErr_Format(PyExc_TypeError, "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", type); + PyErr_Format(PyExc_TypeError, + "RNA Error: unknown type \"%d\" (pyrna_param_to_py)", + type); ret= NULL; break; } @@ -4246,6 +4311,27 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat return ret; } +/* Use to replace PyDict_GetItemString() when the overhead of converting a + * string into a python unicode is higher than a non hash lookup. + * works on small dict's such as keyword args. */ +static PyObject *small_dict_get_item_string(PyObject *dict, const char *key_lookup) +{ + PyObject *key= NULL; + Py_ssize_t pos = 0; + PyObject *value = NULL; + + /* case not, search for it in the script's global dictionary */ + while (PyDict_Next(dict, &pos, &key, &value)) { + if(PyUnicode_Check(key)) { + if(strcmp(key_lookup, _PyUnicode_AsString(key))==0) { + return value; + } + } + } + + return NULL; +} + static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject *kw) { /* Note, both BPy_StructRNA and BPy_PropertyRNA can be used here */ @@ -4258,7 +4344,6 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject PropertyRNA *parm; PyObject *ret, *item; int i, pyargs_len, pykw_len, parms_len, ret_len, flag, err= 0, kw_tot= 0, kw_arg; - const char *parm_id; PropertyRNA *pret_single= NULL; void *retdata_single= NULL; @@ -4334,28 +4419,33 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject continue; } - parm_id= RNA_property_identifier(parm); item= NULL; if (i < pyargs_len) { item= PyTuple_GET_ITEM(args, i); - i++; - kw_arg= FALSE; } else if (kw != NULL) { - item= PyDict_GetItemString(kw, parm_id); /* borrow ref */ +#if 0 + item= PyDict_GetItemString(kw, RNA_property_identifier(parm)); /* borrow ref */ +#else + item= small_dict_get_item_string(kw, RNA_property_identifier(parm)); /* borrow ref */ +#endif if(item) kw_tot++; /* make sure invalid keywords are not given */ kw_arg= TRUE; } + i++; /* current argument */ + if (item==NULL) { if(flag & PROP_REQUIRED) { PyErr_Format(PyExc_TypeError, "%.200s.%.200s(): required parameter \"%.200s\" not specified", - RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), parm_id); + RNA_struct_identifier(self_ptr->type), + RNA_function_identifier(self_func), + RNA_property_identifier(parm)); err= -1; break; } @@ -4382,9 +4472,18 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject PyErr_Clear(); /* re-raise */ if(kw_arg==TRUE) - snprintf(error_prefix, sizeof(error_prefix), "%s.%s(): error with keyword argument \"%s\" - ", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), parm_id); + BLI_snprintf(error_prefix, sizeof(error_prefix), + "%.200s.%.200s(): error with keyword argument \"%.200s\" - ", + RNA_struct_identifier(self_ptr->type), + RNA_function_identifier(self_func), + RNA_property_identifier(parm)); else - snprintf(error_prefix, sizeof(error_prefix), "%s.%s(): error with argument %d, \"%s\" - ", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), i, parm_id); + BLI_snprintf(error_prefix, sizeof(error_prefix), + "%.200s.%.200s(): error with argument %d, \"%.200s\" - ", + RNA_struct_identifier(self_ptr->type), + RNA_function_identifier(self_func), + i, + RNA_property_identifier(parm)); pyrna_py_to_prop(&funcptr, parm, iter.data, item, error_prefix); diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h index b16c8fe2e8c..09fbdf96ed2 100644 --- a/source/blender/python/intern/bpy_util.h +++ b/source/blender/python/intern/bpy_util.h @@ -51,6 +51,7 @@ short BPy_errors_to_report(struct ReportList *reports); struct bContext *BPy_GetContext(void); void BPy_SetContext(struct bContext *C); +extern void bpy_context_update(struct bContext *C); extern void bpy_context_set(struct bContext *C, PyGILState_STATE *gilstate); extern void bpy_context_clear(struct bContext *C, PyGILState_STATE *gilstate); #endif |