diff options
Diffstat (limited to 'source/blender/python/intern')
-rw-r--r-- | source/blender/python/intern/CMakeLists.txt | 3 | ||||
-rw-r--r-- | source/blender/python/intern/bpy.c | 2 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_app.c | 30 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_app_translations.c | 12 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_app_translations.h | 1 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_interface.c | 18 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_props.c | 36 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_rna.c | 32 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_util.c | 60 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_util.h | 3 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_utils_previews.c | 188 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_utils_previews.h | 32 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_utils_units.c | 10 | ||||
-rw-r--r-- | source/blender/python/intern/gpu.c | 31 |
14 files changed, 397 insertions, 61 deletions
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt index 8296027f044..ed04152182e 100644 --- a/source/blender/python/intern/CMakeLists.txt +++ b/source/blender/python/intern/CMakeLists.txt @@ -31,6 +31,7 @@ set(INC ../../blenloader ../../editors/include ../../gpu + ../../imbuf ../../makesdna ../../makesrna ../../windowmanager @@ -69,6 +70,7 @@ set(SRC bpy_rna_callback.c bpy_traceback.c bpy_util.c + bpy_utils_previews.c bpy_utils_units.c stubs.c @@ -94,6 +96,7 @@ set(SRC bpy_rna_callback.h bpy_traceback.h bpy_util.h + bpy_utils_previews.h bpy_utils_units.h ../BPY_extern.h ) diff --git a/source/blender/python/intern/bpy.c b/source/blender/python/intern/bpy.c index ec3c017a7ed..9a5e488850e 100644 --- a/source/blender/python/intern/bpy.c +++ b/source/blender/python/intern/bpy.c @@ -48,6 +48,7 @@ #include "bpy_props.h" #include "bpy_library.h" #include "bpy_operator.h" +#include "bpy_utils_previews.h" #include "bpy_utils_units.h" #include "../generic/py_capi_utils.h" @@ -330,6 +331,7 @@ void BPy_init_modules(void) PyModule_AddObject(mod, "ops", BPY_operator_module()); PyModule_AddObject(mod, "app", BPY_app_struct()); PyModule_AddObject(mod, "_utils_units", BPY_utils_units()); + PyModule_AddObject(mod, "_utils_previews", BPY_utils_previews_module()); /* bpy context */ RNA_pointer_create(NULL, &RNA_Context, (void *)BPy_GetContext(), &ctx_ptr); diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c index c8a4971847b..1cf0c44fd87 100644 --- a/source/blender/python/intern/bpy_app.c +++ b/source/blender/python/intern/bpy_app.c @@ -220,6 +220,33 @@ static int bpy_app_debug_set(PyObject *UNUSED(self), PyObject *value, void *clos return 0; } + + +PyDoc_STRVAR(bpy_app_binary_path_python_doc, +"String, the path to the python executable (read-only)" +); +static PyObject *bpy_app_binary_path_python_get(PyObject *UNUSED(self), void *UNUSED(closure)) +{ + /* refcount is held in BlenderAppType.tp_dict */ + static PyObject *ret = NULL; + + if (ret == NULL) { + /* only run once */ + char fullpath[1024]; + BKE_appdir_program_python_search( + fullpath, sizeof(fullpath), + PY_MAJOR_VERSION, PY_MINOR_VERSION); + ret = PyC_UnicodeFromByte(fullpath); + PyDict_SetItemString(BlenderAppType.tp_dict, "binary_path_python", ret); + } + else { + Py_INCREF(ret); + } + + return ret; + +} + PyDoc_STRVAR(bpy_app_debug_value_doc, "Int, number which can be set to non-zero values for testing purposes" ); @@ -287,6 +314,9 @@ static PyGetSetDef bpy_app_getsets[] = { {(char *)"debug_wm", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_WM}, {(char *)"debug_depsgraph", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_DEPSGRAPH}, {(char *)"debug_simdata", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_SIMDATA}, + {(char *)"debug_gpumem", bpy_app_debug_get, bpy_app_debug_set, (char *)bpy_app_debug_doc, (void *)G_DEBUG_GPU_MEM}, + + {(char *)"binary_path_python", bpy_app_binary_path_python_get, NULL, (char *)bpy_app_binary_path_python_doc, NULL}, {(char *)"debug_value", bpy_app_debug_value_get, bpy_app_debug_value_set, (char *)bpy_app_debug_value_doc, NULL}, {(char *)"tempdir", bpy_app_tempdir_get, NULL, (char *)bpy_app_tempdir_doc, NULL}, diff --git a/source/blender/python/intern/bpy_app_translations.c b/source/blender/python/intern/bpy_app_translations.c index 123b111f3cb..72133badbbb 100644 --- a/source/blender/python/intern/bpy_app_translations.c +++ b/source/blender/python/intern/bpy_app_translations.c @@ -47,8 +47,7 @@ #include "../generic/python_utildefines.h" -typedef struct -{ +typedef struct { PyObject_HEAD /* The string used to separate context from actual message in PY_TRANSLATE RNA props. */ const char *context_separator; @@ -821,3 +820,12 @@ PyObject *BPY_app_translations_struct(void) return ret; } + +void BPY_app_translations_end(void) +{ + /* Incase the object remains in a module's namespace, see T44127. */ +#ifdef WITH_INTERNATIONAL + _clear_translations_cache(); +#endif +} + diff --git a/source/blender/python/intern/bpy_app_translations.h b/source/blender/python/intern/bpy_app_translations.h index 704307574d0..e04c2484ecc 100644 --- a/source/blender/python/intern/bpy_app_translations.h +++ b/source/blender/python/intern/bpy_app_translations.h @@ -28,5 +28,6 @@ #define __BPY_APP_TRANSLATIONS_H__ PyObject *BPY_app_translations_struct(void); +void BPY_app_translations_end(void); #endif /* __BPY_APP_TRANSLATIONS_H__ */ diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index 5b4db89a41a..7e5ad00159e 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -61,6 +61,8 @@ #include "bpy_traceback.h" #include "bpy_intern_string.h" +#include "bpy_app_translations.h" + #include "DNA_text_types.h" #include "BKE_appdir.h" @@ -358,6 +360,9 @@ void BPY_python_end(void) bpy_intern_string_exit(); + /* bpy.app modules that need cleanup */ + BPY_app_translations_end(); + #ifndef WITH_PYTHON_MODULE BPY_atexit_unregister(); /* without this we get recursive calls to WM_exit */ @@ -590,7 +595,7 @@ int BPY_button_exec(bContext *C, const char *expr, double *value, const bool ver if (error_ret) { if (verbose) { - BPy_errors_to_report(CTX_wm_reports(C)); + BPy_errors_to_report_ex(CTX_wm_reports(C), false, false); } else { PyErr_Clear(); @@ -602,7 +607,7 @@ int BPY_button_exec(bContext *C, const char *expr, double *value, const bool ver return error_ret; } -int BPY_string_exec(bContext *C, const char *expr) +int BPY_string_exec_ex(bContext *C, const char *expr, bool use_eval) { PyGILState_STATE gilstate; PyObject *main_mod = NULL; @@ -625,7 +630,7 @@ int BPY_string_exec(bContext *C, const char *expr) bmain_back = bpy_import_main_get(); bpy_import_main_set(CTX_data_main(C)); - retval = PyRun_String(expr, Py_eval_input, py_dict, py_dict); + retval = PyRun_String(expr, use_eval ? Py_eval_input : Py_file_input, py_dict, py_dict); bpy_import_main_set(bmain_back); @@ -645,6 +650,10 @@ int BPY_string_exec(bContext *C, const char *expr) return error_ret; } +int BPY_string_exec(bContext *C, const char *expr) +{ + return BPY_string_exec_ex(C, expr, true); +} void BPY_modules_load_user(bContext *C) { @@ -779,7 +788,6 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult * } #ifdef WITH_PYTHON_MODULE -#include "BLI_fileops.h" /* TODO, reloading the module isn't functional at the moment. */ static void bpy_module_free(void *mod); @@ -831,7 +839,7 @@ static void bpy_module_delay_init(PyObject *bpy_proxy) static void dealloc_obj_dealloc(PyObject *self); -static PyTypeObject dealloc_obj_Type = {{{0}}}; +static PyTypeObject dealloc_obj_Type; /* use our own dealloc so we can free a property if we use one */ static void dealloc_obj_dealloc(PyObject *self) diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c index 8370aea4c99..b0fae243182 100644 --- a/source/blender/python/intern/bpy_props.c +++ b/source/blender/python/intern/bpy_props.c @@ -68,7 +68,8 @@ static EnumPropertyItem property_flag_items[] = { {0, NULL, 0, NULL, NULL}}; #define BPY_PROPDEF_OPTIONS_DOC \ -" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE', 'PROPORTIONAL'].\n" \ +" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE', 'PROPORTIONAL'," \ + "'TEXTEDIT_UPDATE'].\n" \ " :type options: set\n" \ static EnumPropertyItem property_flag_enum_items[] = { @@ -1480,15 +1481,26 @@ static EnumPropertyItem *bpy_prop_enum_itemf_cb(struct bContext *C, PointerRNA * EnumPropertyItem *eitems = NULL; int err = 0; - bpy_context_set(C, &gilstate); + if (C) { + bpy_context_set(C, &gilstate); + } + else { + gilstate = PyGILState_Ensure(); + } args = PyTuple_New(2); self = pyrna_struct_as_instance(ptr); PyTuple_SET_ITEM(args, 0, self); /* now get the context */ - PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module); - Py_INCREF(bpy_context_module); + if (C) { + PyTuple_SET_ITEM(args, 1, (PyObject *)bpy_context_module); + Py_INCREF(bpy_context_module); + } + else { + PyTuple_SET_ITEM(args, 1, Py_None); + Py_INCREF(Py_None); + } items = PyObject_CallObject(py_func, args); @@ -1529,8 +1541,13 @@ static EnumPropertyItem *bpy_prop_enum_itemf_cb(struct bContext *C, PointerRNA * eitems = DummyRNA_NULL_items; } + if (C) { + bpy_context_clear(C, &gilstate); + } + else { + PyGILState_Release(gilstate); + } - bpy_context_clear(C, &gilstate); return eitems; } @@ -2617,7 +2634,7 @@ PyDoc_STRVAR(BPy_EnumProperty_doc, " Note the item is optional.\n" " For dynamic values a callback can be passed which returns a list in\n" " the same format as the static list.\n" -" This function must take 2 arguments (self, context)\n" +" This function must take 2 arguments (self, context), **context may be None**.\n" " WARNING: There is a known bug with using a callback,\n" " Python must keep a reference to the strings returned or Blender will crash.\n" " :type items: sequence of string tuples or a function\n" @@ -2965,9 +2982,10 @@ static struct PyMethodDef props_methods[] = { static struct PyModuleDef props_module = { PyModuleDef_HEAD_INIT, "bpy.props", - "This module defines properties to extend blenders internal data, the result of these functions" - " is used to assign properties to classes registered with blender and can't be used directly.\n" - ".. warning:: All parameters to these functions must be passed as keywords.", + "This module defines properties to extend Blender's internal data. The result of these functions" + " is used to assign properties to classes registered with Blender and can't be used directly.\n" + "\n" + ".. warning:: All parameters to these functions must be passed as keywords.\n", -1, /* multiple "initialization" just copies the module dict. */ props_methods, NULL, NULL, NULL, NULL diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index fadc50e3317..d15e3b36ced 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -53,10 +53,6 @@ #include "bpy_intern_string.h" #ifdef USE_PYRNA_INVALIDATE_WEAKREF -# include "MEM_guardedalloc.h" -#endif - -#ifdef USE_PYRNA_INVALIDATE_WEAKREF # include "BLI_ghash.h" #endif @@ -177,7 +173,7 @@ static GHash *id_weakref_pool_get(ID *id) if (weakinfo_hash == NULL) { /* we're using a ghash as a set, could use libHX's HXMAP_SINGULAR but would be an extra dep. */ weakinfo_hash = BLI_ghash_ptr_new("rna_id"); - BLI_ghash_insert(id_weakref_pool, (void *)id, weakinfo_hash); + BLI_ghash_insert(id_weakref_pool, id, weakinfo_hash); } return weakinfo_hash; @@ -203,7 +199,7 @@ static void id_weakref_pool_add(ID *id, BPy_DummyPointerRNA *pyrna) Py_DECREF(weakref_cb_py); /* function owned by the weakref now */ /* important to add at the end, since first removal looks at the end */ - BLI_ghash_insert(weakinfo_hash, (void *)weakref, id); /* using a hash table as a set, all 'id's are the same */ + BLI_ghash_insert(weakinfo_hash, weakref, id); /* using a hash table as a set, all 'id's are the same */ /* weakinfo_hash owns the weakref */ } @@ -1830,25 +1826,23 @@ static int pyrna_py_to_prop(PointerRNA *ptr, PropertyRNA *prop, void *data, PyOb RNA_property_pointer_set(ptr, prop, param->ptr); } else { + raise_error = true; + } + } + + if (raise_error) { + if (pyrna_struct_validity_check(param) == -1) { + /* error set */ + } + else { PointerRNA tmp; RNA_pointer_create(NULL, ptr_type, NULL, &tmp); PyErr_Format(PyExc_TypeError, - "%.200s %.200s.%.200s expected a %.200s type. not %.200s", + "%.200s %.200s.%.200s expected a %.200s type, not %.200s", error_prefix, RNA_struct_identifier(ptr->type), RNA_property_identifier(prop), RNA_struct_identifier(tmp.type), RNA_struct_identifier(param->ptr.type)); - Py_XDECREF(value_new); return -1; } - } - - if (raise_error) { - PointerRNA tmp; - RNA_pointer_create(NULL, ptr_type, NULL, &tmp); - PyErr_Format(PyExc_TypeError, - "%.200s %.200s.%.200s expected a %.200s type, not %.200s", - error_prefix, RNA_struct_identifier(ptr->type), - RNA_property_identifier(prop), RNA_struct_identifier(tmp.type), - RNA_struct_identifier(param->ptr.type)); Py_XDECREF(value_new); return -1; } } @@ -5241,7 +5235,7 @@ static PyObject *pyrna_func_call(BPy_FunctionRNA *self, PyObject *args, PyObject good_args_str = BLI_dynstr_get_cstring(good_args); PyErr_Format(PyExc_TypeError, - "%.200s.%.200s(): was called with invalid keyword arguments(s) (%s), expected (%s)", + "%.200s.%.200s(): was called with invalid keyword argument(s) (%s), expected (%s)", RNA_struct_identifier(self_ptr->type), RNA_function_identifier(self_func), bad_args_str, good_args_str); diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index 93183a4f320..e876adfa58e 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -82,14 +82,9 @@ short BPy_reports_to_error(ReportList *reports, PyObject *exception, const bool } -short BPy_errors_to_report(ReportList *reports) +bool BPy_errors_to_report_ex(ReportList *reports, const bool use_full, const bool use_location) { PyObject *pystring; - PyObject *pystring_format = NULL; /* workaround, see below */ - const char *cstring; - - const char *filename; - int lineno; if (!PyErr_Occurred()) return 1; @@ -101,31 +96,56 @@ short BPy_errors_to_report(ReportList *reports) return 1; } - pystring = PyC_ExceptionBuffer(); + if (use_full) { + pystring = PyC_ExceptionBuffer(); + } + else { + pystring = PyC_ExceptionBuffer_Simple(); + } if (pystring == NULL) { BKE_report(reports, RPT_ERROR, "Unknown py-exception, could not convert"); return 0; } - - PyC_FileAndNum(&filename, &lineno); - if (filename == NULL) - filename = "<unknown location>"; - - cstring = _PyUnicode_AsString(pystring); + + if (use_location) { + const char *filename; + int lineno; + + PyObject *pystring_format; /* workaround, see below */ + const char *cstring; + + PyC_FileAndNum(&filename, &lineno); + if (filename == NULL) { + filename = "<unknown location>"; + } #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); + BKE_reportf(reports, RPT_ERROR, "%s\nlocation: %s:%d\n", _PyUnicode_AsString(pystring), filename, lineno); #else - pystring_format = PyUnicode_FromFormat(TIP_("%s\nlocation: %s:%d\n"), cstring, filename, lineno); - cstring = _PyUnicode_AsString(pystring_format); - BKE_report(reports, RPT_ERROR, cstring); + pystring_format = PyUnicode_FromFormat( + TIP_("%s\nlocation: %s:%d\n"), + _PyUnicode_AsString(pystring), filename, lineno); + + cstring = _PyUnicode_AsString(pystring_format); + BKE_report(reports, RPT_ERROR, cstring); + + /* not exactly needed. just for testing */ + fprintf(stderr, TIP_("%s\nlocation: %s:%d\n"), cstring, filename, lineno); + + Py_DECREF(pystring_format); /* workaround */ #endif + } + else { + BKE_report(reports, RPT_ERROR, _PyUnicode_AsString(pystring)); + } - /* not exactly needed. just for testing */ - fprintf(stderr, TIP_("%s\nlocation: %s:%d\n"), cstring, filename, lineno); Py_DECREF(pystring); - Py_DECREF(pystring_format); /* workaround */ return 1; } + +bool BPy_errors_to_report(ReportList *reports) +{ + return BPy_errors_to_report_ex(reports, true, true); +}
\ No newline at end of file diff --git a/source/blender/python/intern/bpy_util.h b/source/blender/python/intern/bpy_util.h index d19696aa230..1ae00a7fb02 100644 --- a/source/blender/python/intern/bpy_util.h +++ b/source/blender/python/intern/bpy_util.h @@ -40,7 +40,8 @@ char *BPy_enum_as_string(struct EnumPropertyItem *item); /* error reporting */ short BPy_reports_to_error(struct ReportList *reports, PyObject *exception, const bool clear); -short BPy_errors_to_report(struct ReportList *reports); +bool BPy_errors_to_report_ex(struct ReportList *reports, const bool use_full, const bool use_location); +bool BPy_errors_to_report(struct ReportList *reports); /* TODO - find a better solution! */ struct bContext *BPy_GetContext(void); diff --git a/source/blender/python/intern/bpy_utils_previews.c b/source/blender/python/intern/bpy_utils_previews.c new file mode 100644 index 00000000000..fed7c7210de --- /dev/null +++ b/source/blender/python/intern/bpy_utils_previews.c @@ -0,0 +1,188 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Bastien Montagne + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/python/intern/bpy_utils_previews.c + * \ingroup pythonintern + * + * This file defines a singleton py object accessed via 'bpy.utils.previews', + * which exposes low-level API for custom previews/icons. + * It is replaced in final API by an higher-level python wrapper, that handles previews by addon, + * and automatically release them on deletion. + */ + +#include <Python.h> +#include <structmember.h> + +#include "BLI_utildefines.h" + +#include "RNA_types.h" +#include "RNA_access.h" + +#include "BPY_extern.h" +#include "bpy_utils_previews.h" +#include "bpy_rna.h" + +#include "MEM_guardedalloc.h" + +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" +#include "IMB_thumbs.h" + +#include "BKE_icons.h" + +#include "DNA_ID.h" + +#include "../generic/python_utildefines.h" + +#define STR_SOURCE_TYPES "'IMAGE', 'MOVIE', 'BLEND', 'FONT'" + +PyDoc_STRVAR(bpy_utils_previews_new_doc, +".. method:: new(name)\n" +"\n" +" Generate a new empty preview, or return existing one matching ``name``.\n" +"\n" +" :arg name: The name (unique id) identifying the preview.\n" +" :type name: string\n" +" :return: The Preview matching given name, or a new empty one.\n" +" :rtype: :class:`bpy.types.ImagePreview`\n" +); +static PyObject *bpy_utils_previews_new(PyObject *UNUSED(self), PyObject *args) +{ + char *name; + PreviewImage *prv; + PointerRNA ptr; + + if (!PyArg_ParseTuple(args, "s:new", &name)) { + return NULL; + } + + prv = BKE_previewimg_cached_ensure(name); + RNA_pointer_create(NULL, &RNA_ImagePreview, prv, &ptr); + + return pyrna_struct_CreatePyObject(&ptr); +} + +PyDoc_STRVAR(bpy_utils_previews_load_doc, +".. method:: load(name, filepath, filetype, force_reload=False)\n" +"\n" +" Generate a new preview from given file path, or return existing one matching ``name``.\n" +"\n" +" :arg name: The name (unique id) identifying the preview.\n" +" :type name: string\n" +" :arg filepath: The file path to generate the preview from.\n" +" :type filepath: string\n" +" :arg filetype: The type of file, needed to generate the preview in [" STR_SOURCE_TYPES "].\n" +" :type filetype: string\n" +" :arg force_reload: If True, force running thumbnail manager even if preview already exists in cache.\n" +" :type force_reload: bool\n" +" :return: The Preview matching given name, or a new empty one.\n" +" :rtype: :class:`bpy.types.ImagePreview`\n" +); +static PyObject *bpy_utils_previews_load(PyObject *UNUSED(self), PyObject *args) +{ + char *name, *path, *path_type_s; + int path_type, force_reload = false; + + PreviewImage *prv; + PointerRNA ptr; + + if (!PyArg_ParseTuple( args, "sss|p:load", &name, &path, &path_type_s, &force_reload)) { + return NULL; + } + + if (STREQ(path_type_s, "IMAGE")) { + path_type = THB_SOURCE_IMAGE; + } + else if (STREQ(path_type_s, "MOVIE")) { + path_type = THB_SOURCE_MOVIE; + } + else if (STREQ(path_type_s, "BLEND")) { + path_type = THB_SOURCE_BLEND; + } + else if (STREQ(path_type_s, "FONT")) { + path_type = THB_SOURCE_FONT; + } + else { + PyErr_Format(PyExc_ValueError, + "load: invalid '%s' filetype, only [" STR_SOURCE_TYPES "] " + "are supported", path_type_s); + return NULL; + } + + prv = BKE_previewimg_cached_thumbnail_read(name, path, path_type, force_reload); + RNA_pointer_create(NULL, &RNA_ImagePreview, prv, &ptr); + + return pyrna_struct_CreatePyObject(&ptr); +} + +PyDoc_STRVAR(bpy_utils_previews_release_doc, +".. method:: release(name)\n" +"\n" +" Release (free) a previously created preview.\n" +"\n" +"\n" +" :arg name: The name (unique id) identifying the preview.\n" +" :type name: string\n" +); +static PyObject *bpy_utils_previews_release(PyObject *UNUSED(self), PyObject *args) +{ + char *name; + + if (!PyArg_ParseTuple(args, "s:release", &name)) { + return NULL; + } + + BKE_previewimg_cached_release(name); + + Py_RETURN_NONE; +} + +static struct PyMethodDef bpy_utils_previews_methods[] = { + /* Can't use METH_KEYWORDS alone, see http://bugs.python.org/issue11587 */ + {"new", (PyCFunction)bpy_utils_previews_new, METH_VARARGS, bpy_utils_previews_new_doc}, + {"load", (PyCFunction)bpy_utils_previews_load, METH_VARARGS, bpy_utils_previews_load_doc}, + {"release", (PyCFunction)bpy_utils_previews_release, METH_VARARGS, bpy_utils_previews_release_doc}, + {NULL, NULL, 0, NULL} +}; + +PyDoc_STRVAR(bpy_utils_previews_doc, +"This object contains basic static methods to handle cached (non-ID) previews in Blender\n" +"(low-level API, not exposed to final users)." +); +static struct PyModuleDef bpy_utils_previews_module = { + PyModuleDef_HEAD_INIT, + "bpy._utils_previews", + bpy_utils_previews_doc, + 0, + bpy_utils_previews_methods, + NULL, NULL, NULL, NULL +}; + + +PyObject *BPY_utils_previews_module(void) +{ + PyObject *submodule; + + submodule = PyModule_Create(&bpy_utils_previews_module); + + return submodule; +} diff --git a/source/blender/python/intern/bpy_utils_previews.h b/source/blender/python/intern/bpy_utils_previews.h new file mode 100644 index 00000000000..3d7ade04b9f --- /dev/null +++ b/source/blender/python/intern/bpy_utils_previews.h @@ -0,0 +1,32 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Contributor(s): Bastien Montagne + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/python/intern/bpy_utils_previews.h + * \ingroup pythonintern + */ + +#ifndef __BPY_UTILS_PREVIEWS_H__ +#define __BPY_UTILS_PREVIEWS_H__ + +PyObject *BPY_utils_previews_module(void); + +#endif /* __BPY_UTILS_PREVIEWS_H__ */ diff --git a/source/blender/python/intern/bpy_utils_units.c b/source/blender/python/intern/bpy_utils_units.c index a6df8f54cc3..d40e7e070ac 100644 --- a/source/blender/python/intern/bpy_utils_units.c +++ b/source/blender/python/intern/bpy_utils_units.c @@ -155,18 +155,18 @@ static bool bpyunits_validate(const char *usys_str, const char *ucat_str, int *r } PyDoc_STRVAR(bpyunits_to_value_doc, -".. method:: to_value(unit_system, unit_category, str_input, [str_ref_unit=None])\n" +".. method:: to_value(unit_system, unit_category, str_input, str_ref_unit=None)\n" "\n" " Convert a given input string into a float value.\n" "\n" " :arg unit_system: The unit system, from :attr:`bpy.utils.units.systems`.\n" " :type unit_system: string\n" -" :arg unit_category: The category of data we are converting (length, area, rotation, etc.), " +" :arg unit_category: The category of data we are converting (length, area, rotation, etc.),\n" " from :attr:`bpy.utils.units.categories`.\n" " :type unit_category: string\n" " :arg str_input: The string to convert to a float value.\n" " :type str_input: string\n" -" :arg str_ref_unit: A reference string from which to extract a default unit, if none is found in :arg:`str_input`.\n" +" :arg str_ref_unit: A reference string from which to extract a default unit, if none is found in ``str_input``.\n" " :type str_ref_unit: string or None\n" " :return: The converted/interpreted value.\n" " :rtype: float\n" @@ -221,13 +221,13 @@ static PyObject *bpyunits_to_value(PyObject *UNUSED(self), PyObject *args, PyObj } PyDoc_STRVAR(bpyunits_to_string_doc, -".. method:: to_string(unit_system, unit_category, value, [precision=3, [split_unit=False, [compatible_unit=False]]])\n" +".. method:: to_string(unit_system, unit_category, value, precision=3, split_unit=False, compatible_unit=False)\n" "\n" " Convert a given input float value into a string with units.\n" "\n" " :arg unit_system: The unit system, from :attr:`bpy.utils.units.systems`.\n" " :type unit_system: string\n" -" :arg unit_category: The category of data we are converting (length, area, rotation, etc.), " +" :arg unit_category: The category of data we are converting (length, area, rotation, etc.),\n" " from :attr:`bpy.utils.units.categories`.\n" " :type unit_category: string\n" " :arg value: The value to convert to a string.\n" diff --git a/source/blender/python/intern/gpu.c b/source/blender/python/intern/gpu.c index e4580e8035b..f933c02390c 100644 --- a/source/blender/python/intern/gpu.c +++ b/source/blender/python/intern/gpu.c @@ -79,7 +79,17 @@ static PyObject *PyInit_gpu(void) if (m == NULL) return NULL; + /* device constant groups */ + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_GROUP_MISC); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_GROUP_LAMP); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_GROUP_OBJECT); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_GROUP_SAMPLER); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_GROUP_MIST); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_GROUP_WORLD); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_GROUP_MAT); + /* device constants */ + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_NONE); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_VIEWMAT); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_MAT); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_OBJECT_VIEWIMAT); @@ -92,9 +102,30 @@ static PyObject *PyInit_gpu(void) PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNPERSMAT); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNENERGY); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DYNCOL); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_ATT1); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_ATT2); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_DISTANCE); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_SPOTBLEND); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_LAMP_SPOTSIZE); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DBUFFER); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DIMAGE); PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_SAMPLER_2DSHADOW); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_ENABLE); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_START); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_DISTANCE); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_INTENSITY); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_TYPE); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MIST_COLOR); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_HORIZON_COLOR); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_AMBIENT_COLOR); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_ALPHA); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_AMB); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_DIFFRGB); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_EMIT); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_HARD); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_REF); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_SPEC); + PY_MODULE_ADD_CONSTANT(m, GPU_DYNAMIC_MAT_SPECRGB); PY_MODULE_ADD_CONSTANT(m, GPU_DATA_1I); PY_MODULE_ADD_CONSTANT(m, GPU_DATA_1F); |