added mb-0014 and mb-0015

This commit is contained in:
Jaume Bellet 2023-11-20 23:02:08 +01:00
parent 33914c92cc
commit e084874db7
17 changed files with 717 additions and 45 deletions

View File

@ -354,12 +354,12 @@ index ab73ab435ca..cba61b7a15d 100644
if(HAVE_FEENABLEEXCEPT)
diff --git a/source/creator/creator.cc b/source/creator/creator.cc
index 7e6815ee286..3fe843a6a5c 100644
index 70c7003661d..ad44b3048ad 100644
--- a/source/creator/creator.cc
+++ b/source/creator/creator.cc
@@ -57,6 +57,8 @@
#include "BKE_vfont.h"
#include "BKE_volume.h"
#include "BKE_volume.hh"
+#include "MB_blender.h"
+
@ -376,7 +376,7 @@ index 7e6815ee286..3fe843a6a5c 100644
/* The settings pass includes:
* - Background-mode assignment (#Global.background), checked by other subsystems
diff --git a/source/creator/creator_args.cc b/source/creator/creator_args.cc
index 502f7f37267..6dd68668b18 100644
index b13875d19de..84d66f7312b 100644
--- a/source/creator/creator_args.cc
+++ b/source/creator/creator_args.cc
@@ -47,6 +47,8 @@

View File

@ -0,0 +1,319 @@
diff --git a/scripts/modules/bpy/utils/images.py b/scripts/modules/bpy/utils/images.py
new file mode 100644
index 00000000000..b4bd02b395c
--- /dev/null
+++ b/scripts/modules/bpy/utils/images.py
@@ -0,0 +1,49 @@
+# SPDX-FileCopyrightText: 2015-2023 Blender Authors
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+"""
+This module contains utility functions to handle custom images.
+"""
+
+__all__ = (
+ "load",
+ "release"
+ "list",
+)
+
+from _bpy import _utils_images
+
+
+list = []
+
+
+def load(name, path):
+ r = _utils_images.load(name, path)
+ if r != None:
+ data = {'id' : r , 'name' : name, 'path' : path}
+ list.append(data)
+ return data;
+ else:
+ return None;
+
+load.__doc__ = _utils_images.load.__doc__;
+
+def release(image_id):
+ r = _utils_images.release(image_id)
+ if r == True:
+ for data in list:
+ if data.get('id') == image_id:
+ list.remove(data)
+
+ return r;
+release.__doc__ = _utils_images.release.__doc__
+
+import atexit
+
+def exit_clear():
+ while len(list):
+ release(list[0].get('id'))
+
+atexit.register(exit_clear)
+del atexit, exit_clear
diff --git a/source/blender/mblender/patches/MB_0014.h b/source/blender/mblender/patches/MB_0014.h
new file mode 100644
index 00000000000..ddf2a41c228
--- /dev/null
+++ b/source/blender/mblender/patches/MB_0014.h
@@ -0,0 +1 @@
+/* Empty File */
diff --git a/source/blender/python/BPY_extern.h b/source/blender/python/BPY_extern.h
index db70947b683..3a00f2767f2 100644
--- a/source/blender/python/BPY_extern.h
+++ b/source/blender/python/BPY_extern.h
@@ -133,6 +133,8 @@ bool BPY_string_is_keyword(const char *str);
void BPY_callback_screen_free(struct ARegionType *art);
void BPY_callback_wm_free(struct wmWindowManager *wm);
+void* BPY_utils_images_get(int image_id);
+
/* I18n for addons */
#ifdef WITH_INTERNATIONAL
const char *BPY_app_translations_py_pgettext(const char *msgctxt, const char *msgid);
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index fd5a04369b7..3a364ff773e 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -70,6 +70,7 @@ set(SRC
bpy_rna_ui.cc
bpy_traceback.cc
bpy_utils_previews.cc
+ bpy_utils_images.cc
bpy_utils_units.cc
stubs.cc
@@ -112,6 +113,7 @@ set(SRC
bpy_rna_ui.h
bpy_traceback.h
bpy_utils_previews.h
+ bpy_utils_images.h
bpy_utils_units.h
../BPY_extern.h
../BPY_extern_clog.h
diff --git a/source/blender/python/intern/bpy.cc b/source/blender/python/intern/bpy.cc
index 30568703cc3..9ba51867d28 100644
--- a/source/blender/python/intern/bpy.cc
+++ b/source/blender/python/intern/bpy.cc
@@ -46,6 +46,7 @@
#include "bpy_rna_id_collection.h"
#include "bpy_rna_types_capi.h"
#include "bpy_utils_previews.h"
+#include "bpy_utils_images.h"
#include "bpy_utils_units.h"
#include "../generic/py_capi_utils.h"
@@ -686,6 +687,7 @@ void BPy_init_modules(bContext *C)
PyModule_AddObject(mod, "app", BPY_app_struct());
PyModule_AddObject(mod, "_utils_units", BPY_utils_units());
PyModule_AddObject(mod, "_utils_previews", BPY_utils_previews_module());
+ PyModule_AddObject(mod, "_utils_images", BPY_utils_images_module());
PyModule_AddObject(mod, "msgbus", BPY_msgbus_module());
PointerRNA ctx_ptr = RNA_pointer_create(nullptr, &RNA_Context, C);
diff --git a/source/blender/python/intern/bpy_utils_images.cc b/source/blender/python/intern/bpy_utils_images.cc
new file mode 100644
index 00000000000..a35ae852fb7
--- /dev/null
+++ b/source/blender/python/intern/bpy_utils_images.cc
@@ -0,0 +1,173 @@
+/* SPDX-FileCopyrightText: 2023 Blender Authors
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup pythonintern
+ *
+ * This file defines a singleton py object accessed via 'bpy.utils.images',
+ */
+
+#include <Python.h>
+#include <structmember.h>
+
+#include <string.h>
+
+#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
+#include "BLI_string.h"
+
+#include "RNA_access.hh"
+#include "RNA_prototypes.h"
+#include "RNA_types.hh"
+
+#include "BPY_extern.h"
+#include "bpy_rna.h"
+#include "bpy_utils_images.h"
+
+#include "../generic/py_capi_utils.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "IMB_imbuf.h"
+
+#include "../generic/python_utildefines.h"
+
+
+struct bpy_image_data{
+ bpy_image_data *prev;
+ bpy_image_data *next;
+
+ int id;
+ ImBuf *ibuf;
+ std::string name;
+ std::string path;
+};
+
+int bpy_images_last_id = 0;
+ListBase bpy_images_list;
+
+
+bpy_image_data* BPY_utils_images_get_data(int image_id) {
+ return (bpy_image_data *)BLI_listbase_bytes_find(
+ &bpy_images_list, &image_id, sizeof(int), sizeof(bpy_image_data *) * 2);
+}
+
+void* BPY_utils_images_get(int image_id)
+{
+ bpy_image_data *el = BPY_utils_images_get_data(image_id);
+ return (el != nullptr) ? el->ibuf : nullptr;
+}
+
+PyDoc_STRVAR(bpy_utils_images_load_doc,
+ ".. method:: load(name, filepath)\n"
+ "\n"
+ " Generate a new preview from given file path.\n"
+ "\n"
+ " :arg name: The name identifying the image.\n"
+ " :type name: string\n"
+ " :arg filepath: The file path to the image.\n"
+ " :type filepath: string or bytes\n"
+ " :return: image id.\n"
+ " :rtype: long`\n");
+static PyObject *bpy_utils_images_load(PyObject * /*self*/, PyObject *args)
+{
+ char *name = NULL;
+ PyC_UnicodeAsBytesAndSize_Data filepath_data = {nullptr};
+
+ if (!PyArg_ParseTuple(args,
+ "s" /* `name` */
+ "O&" /* `filepath` */
+ ":load",
+ &name,
+ PyC_ParseUnicodeAsBytesAndSize,
+ &filepath_data,
+ 0))
+ {
+ return nullptr;
+ }
+
+ if (!filepath_data.value || !name) {
+ Py_RETURN_NONE;
+ }
+
+ ImBuf *ibuf = IMB_loadiffname(filepath_data.value, 0, nullptr);
+
+ if (ibuf) {
+ bpy_image_data *data = MEM_new<bpy_image_data>(__func__);
+ data->id = ++bpy_images_last_id;
+ data->ibuf = ibuf;
+ data->name = name;
+ data->path = filepath_data.value;
+
+ BLI_addtail(&bpy_images_list, data);
+
+ return PyLong_FromLong(data->id);
+ }
+ else {
+ Py_RETURN_NONE;
+ }
+}
+
+PyDoc_STRVAR(bpy_utils_images_release_doc,
+ ".. method:: release(image_id)\n"
+ "\n"
+ " Release (free) a previously added image.\n"
+ "\n"
+ "\n"
+ " :arg image_id: The id identifying the image.\n"
+ " :type name: long\n"
+ " :return: true if release.\n"
+ " :rtype: bool`\n");
+static PyObject *bpy_utils_images_release(PyObject * /*self*/, PyObject *args)
+{
+ int image_id = -1;
+
+ if (!PyArg_ParseTuple(args, "i:release", &image_id)) {
+ return nullptr;
+ }
+
+ bpy_image_data *el = BPY_utils_images_get_data(image_id);
+
+ if (el != nullptr) {
+ BLI_remlink(&bpy_images_list, el);
+ IMB_freeImBuf(el->ibuf);
+ MEM_freeN(el);
+ Py_RETURN_TRUE;
+ }
+ else {
+ Py_RETURN_FALSE;
+ }
+}
+
+static PyMethodDef bpy_utils_images_methods[] = {
+ /* Can't use METH_KEYWORDS alone, see http://bugs.python.org/issue11587 */
+ {"load", (PyCFunction)bpy_utils_images_load, METH_VARARGS, bpy_utils_images_load_doc},
+ {"release",(PyCFunction)bpy_utils_images_release,METH_VARARGS, bpy_utils_images_release_doc},
+ {nullptr, nullptr, 0, nullptr},
+};
+
+PyDoc_STRVAR(
+ bpy_utils_images_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 PyModuleDef bpy_utils_images_module = {
+ /*m_base*/ PyModuleDef_HEAD_INIT,
+ /*m_name*/ "bpy._utils_images",
+ /*m_doc*/ bpy_utils_images_doc,
+ /*m_size*/ 0,
+ /*m_methods*/ bpy_utils_images_methods,
+ /*m_slots*/ nullptr,
+ /*m_traverse*/ nullptr,
+ /*m_clear*/ nullptr,
+ /*m_free*/ nullptr,
+};
+
+PyObject *BPY_utils_images_module()
+{
+ PyObject *submodule;
+
+ submodule = PyModule_Create(&bpy_utils_images_module);
+
+ return submodule;
+}
diff --git a/source/blender/python/intern/bpy_utils_images.h b/source/blender/python/intern/bpy_utils_images.h
new file mode 100644
index 00000000000..6e27babe26a
--- /dev/null
+++ b/source/blender/python/intern/bpy_utils_images.h
@@ -0,0 +1,19 @@
+/* SPDX-FileCopyrightText: 2023 Blender Authors
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup pythonintern
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyObject *BPY_utils_images_module(void);
+
+#ifdef __cplusplus
+}
+#endif

View File

@ -0,0 +1,99 @@
diff --git a/source/blender/editors/include/UI_interface_c.hh b/source/blender/editors/include/UI_interface_c.hh
index b736a2d7cf0..a2b5bf9b6b0 100644
--- a/source/blender/editors/include/UI_interface_c.hh
+++ b/source/blender/editors/include/UI_interface_c.hh
@@ -2433,6 +2433,9 @@ void uiTemplatePreview(uiLayout *layout,
MTex *slot,
const char *preview_id);
void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname, bool expand);
+
+void uiTemplateImageUI(uiLayout *layout, int image_id, float image_scale);
+
/**
* \param icon_scale: Scale of the icon, 1x == button height.
*/
diff --git a/source/blender/editors/interface/interface_templates.cc b/source/blender/editors/interface/interface_templates.cc
index 16bd571818b..db80180a653 100644
--- a/source/blender/editors/interface/interface_templates.cc
+++ b/source/blender/editors/interface/interface_templates.cc
@@ -78,6 +78,9 @@
#include "ED_render.hh"
#include "ED_screen.hh"
#include "ED_undo.hh"
+#include "ED_datafiles.h"
+
+#include "IMB_imbuf.h"
#include "RE_engine.h"
@@ -93,6 +96,8 @@
#include "UI_view2d.hh"
#include "interface_intern.hh"
+#include "BPY_extern.h"
+
#include "PIL_time.h"
/* we may want to make this optional, disable for now. */
@@ -3369,6 +3374,28 @@ void uiTemplatePreview(uiLayout *layout,
/** \} */
+void uiTemplateImageUI(uiLayout* layout, int image_id,float image_scale) {
+
+ ImBuf *ibuf = IMB_dupImBuf((ImBuf *) BPY_utils_images_get(image_id));
+
+ if (ibuf) {
+ int width = ibuf->x * image_scale;
+ int height = (width * ibuf->y) / ibuf->x;
+
+ IMB_premultiply_alpha(ibuf);
+ IMB_scaleImBuf(ibuf, width, height);
+
+ bTheme *btheme = UI_GetTheme();
+ uchar *color = btheme->tui.wcol_menu_back.text_sel;
+ //color = btheme->tui.wcol_box.inner;
+
+ uiBlock *block = uiLayoutAbsoluteBlock(layout);
+
+ uiBut *but = uiDefButImage(block, ibuf, 0, U.widget_unit, width, height, color);
+
+ }
+}
+
/* -------------------------------------------------------------------- */
/** \name ColorRamp Template
* \{ */
diff --git a/source/blender/makesrna/intern/rna_ui_api.cc b/source/blender/makesrna/intern/rna_ui_api.cc
index b04e1ba5c3b..88311532e05 100644
--- a/source/blender/makesrna/intern/rna_ui_api.cc
+++ b/source/blender/makesrna/intern/rna_ui_api.cc
@@ -1666,6 +1666,21 @@ void RNA_api_ui_layout(StructRNA *srna)
1.0f,
100.0f);
+
+ func = RNA_def_function(srna, "template_image_ui", "uiTemplateImageUI");
+ RNA_def_function_ui_description(func, "A image on UI");
+ parm = RNA_def_int(func, "image_value", 0, 0, INT_MAX, "image to display", "", 0, INT_MAX);
+ RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
+ RNA_def_float(func,
+ "scale",
+ 1.0f,
+ 1.0f,
+ 100.0f,
+ "Scale",
+ "Scale the icon size (by the button size)",
+ 1.0f,
+ 100.0f);
+
func = RNA_def_function(srna, "template_icon_view", "uiTemplateIconView");
RNA_def_function_ui_description(func, "Enum. Large widget showing Icon previews");
api_ui_item_rna_common(func);
diff --git a/source/blender/mblender/patches/MB_0015.h b/source/blender/mblender/patches/MB_0015.h
new file mode 100644
index 00000000000..ddf2a41c228
--- /dev/null
+++ b/source/blender/mblender/patches/MB_0015.h
@@ -0,0 +1 @@
+/* Empty File */

View File

@ -1,24 +0,0 @@
import subprocess
import os
import patches
url = "https://mechanicalblender.org/mblender_patches/patches/"
path = os.path.join(os.path.dirname(__file__),"applied")
if not os.path.exists(path):
os.makedirs(path)
for name in patches.names:
file = name + ".patch"
remote = url + file
local = os.path.join(path, file)
#curl --ssl-no-revoke https://mechanicalblender.org/mblender_patches/patches/mb-0007-transform-flags.patch > mblender\applied\mb-0007-transform-flags.patch
print (remote)
with open (local, "wb") as pfile:
subprocess.run(['curl', '--ssl-no-revoke', remote], stdout=pfile)
subprocess.run(['git', 'apply', local])

View File

@ -5,4 +5,5 @@ names.append("mb-0008-mblender-core")
names.append("mb-0009-addon-menu-references")
names.append("mb-0010-url-presets")
names.append("mb-0012-custom-splash")
names.append("mb-0014-bpy-images")
names.append("mb-0015-image-ui")

View File

@ -1,17 +0,0 @@
import subprocess
import os
import patches
path = os.path.join(os.path.dirname(__file__),"applied")
for name in patches.names:
file = name + ".patch"
local = os.path.join(path, file)
if (os.path.isfile (local)):
subprocess.run(['git', 'apply', '-R', local])
os.remove(local)
os.remove (__file__)
os.remove(os.path.join(os.path.dirname(__file__), "apply.py"))
os.remove(os.path.join(os.path.dirname(__file__), "patches.py"))

View File

@ -0,0 +1,49 @@
# SPDX-FileCopyrightText: 2015-2023 Blender Authors
#
# SPDX-License-Identifier: GPL-2.0-or-later
"""
This module contains utility functions to handle custom images.
"""
__all__ = (
"load",
"release"
"list",
)
from _bpy import _utils_images
list = []
def load(name, path):
r = _utils_images.load(name, path)
if r != None:
data = {'id' : r , 'name' : name, 'path' : path}
list.append(data)
return data;
else:
return None;
load.__doc__ = _utils_images.load.__doc__;
def release(image_id):
r = _utils_images.release(image_id)
if r == True:
for data in list:
if data.get('id') == image_id:
list.remove(data)
return r;
release.__doc__ = _utils_images.release.__doc__
import atexit
def exit_clear():
while len(list):
release(list[0].get('id'))
atexit.register(exit_clear)
del atexit, exit_clear

View File

@ -2435,6 +2435,9 @@ void uiTemplatePreview(uiLayout *layout,
MTex *slot,
const char *preview_id);
void uiTemplateColorRamp(uiLayout *layout, PointerRNA *ptr, const char *propname, bool expand);
void uiTemplateImageUI(uiLayout *layout, int image_id, float image_scale);
/**
* \param icon_scale: Scale of the icon, 1x == button height.
*/

View File

@ -78,6 +78,9 @@
#include "ED_render.hh"
#include "ED_screen.hh"
#include "ED_undo.hh"
#include "ED_datafiles.h"
#include "IMB_imbuf.h"
#include "RE_engine.h"
@ -93,6 +96,8 @@
#include "UI_view2d.hh"
#include "interface_intern.hh"
#include "BPY_extern.h"
#include "PIL_time.h"
/* we may want to make this optional, disable for now. */
@ -3369,6 +3374,28 @@ void uiTemplatePreview(uiLayout *layout,
/** \} */
void uiTemplateImageUI(uiLayout* layout, int image_id,float image_scale) {
ImBuf *ibuf = IMB_dupImBuf((ImBuf *) BPY_utils_images_get(image_id));
if (ibuf) {
int width = ibuf->x * image_scale;
int height = (width * ibuf->y) / ibuf->x;
IMB_premultiply_alpha(ibuf);
IMB_scaleImBuf(ibuf, width, height);
bTheme *btheme = UI_GetTheme();
uchar *color = btheme->tui.wcol_menu_back.text_sel;
//color = btheme->tui.wcol_box.inner;
uiBlock *block = uiLayoutAbsoluteBlock(layout);
uiBut *but = uiDefButImage(block, ibuf, 0, U.widget_unit, width, height, color);
}
}
/* -------------------------------------------------------------------- */
/** \name ColorRamp Template
* \{ */

View File

@ -1782,6 +1782,21 @@ void RNA_api_ui_layout(StructRNA *srna)
1.0f,
100.0f);
func = RNA_def_function(srna, "template_image_ui", "uiTemplateImageUI");
RNA_def_function_ui_description(func, "A image on UI");
parm = RNA_def_int(func, "image_value", 0, 0, INT_MAX, "image to display", "", 0, INT_MAX);
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
RNA_def_float(func,
"scale",
1.0f,
1.0f,
100.0f,
"Scale",
"Scale the icon size (by the button size)",
1.0f,
100.0f);
func = RNA_def_function(srna, "template_icon_view", "uiTemplateIconView");
RNA_def_function_ui_description(func, "Enum. Large widget showing Icon previews");
api_ui_item_rna_common(func);

View File

@ -0,0 +1 @@
/* Empty File */

View File

@ -0,0 +1 @@
/* Empty File */

View File

@ -133,6 +133,8 @@ bool BPY_string_is_keyword(const char *str);
void BPY_callback_screen_free(struct ARegionType *art);
void BPY_callback_wm_free(struct wmWindowManager *wm);
void* BPY_utils_images_get(int image_id);
/* I18n for addons */
#ifdef WITH_INTERNATIONAL
const char *BPY_app_translations_py_pgettext(const char *msgctxt, const char *msgid);

View File

@ -70,6 +70,7 @@ set(SRC
bpy_rna_ui.cc
bpy_traceback.cc
bpy_utils_previews.cc
bpy_utils_images.cc
bpy_utils_units.cc
stubs.cc
@ -112,6 +113,7 @@ set(SRC
bpy_rna_ui.h
bpy_traceback.h
bpy_utils_previews.h
bpy_utils_images.h
bpy_utils_units.h
../BPY_extern.h
../BPY_extern_clog.h

View File

@ -46,6 +46,7 @@
#include "bpy_rna_id_collection.h"
#include "bpy_rna_types_capi.h"
#include "bpy_utils_previews.h"
#include "bpy_utils_images.h"
#include "bpy_utils_units.h"
#include "../generic/py_capi_utils.h"
@ -686,6 +687,7 @@ void BPy_init_modules(bContext *C)
PyModule_AddObject(mod, "app", BPY_app_struct());
PyModule_AddObject(mod, "_utils_units", BPY_utils_units());
PyModule_AddObject(mod, "_utils_previews", BPY_utils_previews_module());
PyModule_AddObject(mod, "_utils_images", BPY_utils_images_module());
PyModule_AddObject(mod, "msgbus", BPY_msgbus_module());
PointerRNA ctx_ptr = RNA_pointer_create(nullptr, &RNA_Context, C);

View File

@ -0,0 +1,173 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup pythonintern
*
* This file defines a singleton py object accessed via 'bpy.utils.images',
*/
#include <Python.h>
#include <structmember.h>
#include <string.h>
#include "BLI_utildefines.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "RNA_access.hh"
#include "RNA_prototypes.h"
#include "RNA_types.hh"
#include "BPY_extern.h"
#include "bpy_rna.h"
#include "bpy_utils_images.h"
#include "../generic/py_capi_utils.h"
#include "MEM_guardedalloc.h"
#include "IMB_imbuf.h"
#include "../generic/python_utildefines.h"
struct bpy_image_data{
bpy_image_data *prev;
bpy_image_data *next;
int id;
ImBuf *ibuf;
std::string name;
std::string path;
};
int bpy_images_last_id = 0;
ListBase bpy_images_list;
bpy_image_data* BPY_utils_images_get_data(int image_id) {
return (bpy_image_data *)BLI_listbase_bytes_find(
&bpy_images_list, &image_id, sizeof(int), sizeof(bpy_image_data *) * 2);
}
void* BPY_utils_images_get(int image_id)
{
bpy_image_data *el = BPY_utils_images_get_data(image_id);
return (el != nullptr) ? el->ibuf : nullptr;
}
PyDoc_STRVAR(bpy_utils_images_load_doc,
".. method:: load(name, filepath)\n"
"\n"
" Generate a new preview from given file path.\n"
"\n"
" :arg name: The name identifying the image.\n"
" :type name: string\n"
" :arg filepath: The file path to the image.\n"
" :type filepath: string or bytes\n"
" :return: image id.\n"
" :rtype: long`\n");
static PyObject *bpy_utils_images_load(PyObject * /*self*/, PyObject *args)
{
char *name = NULL;
PyC_UnicodeAsBytesAndSize_Data filepath_data = {nullptr};
if (!PyArg_ParseTuple(args,
"s" /* `name` */
"O&" /* `filepath` */
":load",
&name,
PyC_ParseUnicodeAsBytesAndSize,
&filepath_data,
0))
{
return nullptr;
}
if (!filepath_data.value || !name) {
Py_RETURN_NONE;
}
ImBuf *ibuf = IMB_loadiffname(filepath_data.value, 0, nullptr);
if (ibuf) {
bpy_image_data *data = MEM_new<bpy_image_data>(__func__);
data->id = ++bpy_images_last_id;
data->ibuf = ibuf;
data->name = name;
data->path = filepath_data.value;
BLI_addtail(&bpy_images_list, data);
return PyLong_FromLong(data->id);
}
else {
Py_RETURN_NONE;
}
}
PyDoc_STRVAR(bpy_utils_images_release_doc,
".. method:: release(image_id)\n"
"\n"
" Release (free) a previously added image.\n"
"\n"
"\n"
" :arg image_id: The id identifying the image.\n"
" :type name: long\n"
" :return: true if release.\n"
" :rtype: bool`\n");
static PyObject *bpy_utils_images_release(PyObject * /*self*/, PyObject *args)
{
int image_id = -1;
if (!PyArg_ParseTuple(args, "i:release", &image_id)) {
return nullptr;
}
bpy_image_data *el = BPY_utils_images_get_data(image_id);
if (el != nullptr) {
BLI_remlink(&bpy_images_list, el);
IMB_freeImBuf(el->ibuf);
MEM_freeN(el);
Py_RETURN_TRUE;
}
else {
Py_RETURN_FALSE;
}
}
static PyMethodDef bpy_utils_images_methods[] = {
/* Can't use METH_KEYWORDS alone, see http://bugs.python.org/issue11587 */
{"load", (PyCFunction)bpy_utils_images_load, METH_VARARGS, bpy_utils_images_load_doc},
{"release",(PyCFunction)bpy_utils_images_release,METH_VARARGS, bpy_utils_images_release_doc},
{nullptr, nullptr, 0, nullptr},
};
PyDoc_STRVAR(
bpy_utils_images_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 PyModuleDef bpy_utils_images_module = {
/*m_base*/ PyModuleDef_HEAD_INIT,
/*m_name*/ "bpy._utils_images",
/*m_doc*/ bpy_utils_images_doc,
/*m_size*/ 0,
/*m_methods*/ bpy_utils_images_methods,
/*m_slots*/ nullptr,
/*m_traverse*/ nullptr,
/*m_clear*/ nullptr,
/*m_free*/ nullptr,
};
PyObject *BPY_utils_images_module()
{
PyObject *submodule;
submodule = PyModule_Create(&bpy_utils_images_module);
return submodule;
}

View File

@ -0,0 +1,19 @@
/* SPDX-FileCopyrightText: 2023 Blender Authors
*
* SPDX-License-Identifier: GPL-2.0-or-later */
/** \file
* \ingroup pythonintern
*/
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
PyObject *BPY_utils_images_module(void);
#ifdef __cplusplus
}
#endif