[Bf-blender-cvs] [1287fa3f7c5] blender2.8: UI: option to load icon from file

Campbell Barton noreply at git.blender.org
Mon Apr 23 20:25:13 CEST 2018


Commit: 1287fa3f7c5a0dc4484aa7e94267d21cc8b0b1f0
Author: Campbell Barton
Date:   Mon Apr 23 20:16:32 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB1287fa3f7c5a0dc4484aa7e94267d21cc8b0b1f0

UI: option to load icon from file

===================================================================

M	source/blender/blenkernel/BKE_icons.h
M	source/blender/blenkernel/intern/icons.c
M	source/blender/python/intern/bpy_app_icons.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h
index fb40e5be281..ffcbd231524 100644
--- a/source/blender/blenkernel/BKE_icons.h
+++ b/source/blender/blenkernel/BKE_icons.h
@@ -65,8 +65,11 @@ struct Icon {
 struct Icon_Geom {
 	int icon_id;
 	int coords_len;
+	int coords_range[2];
 	const unsigned char (*coords)[2];
 	const unsigned char (*colors)[4];
+	/* when not NULL, the memory of coords and colors is a sub-region of this pointer. */
+	const void *mem;
 };
 
 typedef struct Icon Icon;
@@ -84,8 +87,6 @@ int BKE_icon_id_ensure(struct ID *id);
 
 int BKE_icon_preview_ensure(struct ID *id, struct PreviewImage *preview);
 
-int BKE_icon_geom_ensure(struct Icon_Geom *geom);
-
 /* retrieve icon for id */
 struct Icon *BKE_icon_get(const int icon_id);
 
@@ -149,6 +150,9 @@ struct PreviewImage *BKE_previewimg_cached_thumbnail_read(
 void BKE_previewimg_cached_release(const char *name);
 void BKE_previewimg_cached_release_pointer(struct PreviewImage *prv);
 
+int BKE_icon_geom_ensure(struct Icon_Geom *geom);
+struct Icon_Geom *BKE_icon_geom_from_file(const char *filename);
+
 struct ImBuf *BKE_icon_geom_rasterize(
         const struct Icon_Geom *geom,
         const unsigned int size_x, const unsigned int size_y);
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index 7097b349125..e47d6761690 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -51,6 +51,7 @@
 #include "BLI_ghash.h"
 #include "BLI_linklist_lockfree.h"
 #include "BLI_string.h"
+#include "BLI_fileops.h"
 #include "BLI_threads.h"
 
 #include "BKE_icons.h"
@@ -96,8 +97,14 @@ static void icon_free(void *val)
 	if (icon) {
 		if (icon->obj_type == ICON_DATA_GEOM) {
 			struct Icon_Geom *obj = icon->obj;
-			MEM_freeN((void *)obj->coords);
-			MEM_freeN((void *)obj->colors);
+			if (obj->mem) {
+				/* coords & colors are part of this memory. */
+				MEM_freeN((void *)obj->mem);
+			}
+			else {
+				MEM_freeN((void *)obj->coords);
+				MEM_freeN((void *)obj->colors);
+			}
 			MEM_freeN(icon->obj);
 		}
 
@@ -621,22 +628,6 @@ int BKE_icon_preview_ensure(ID *id, PreviewImage *preview)
 	return preview->icon_id;
 }
 
-int BKE_icon_geom_ensure(struct Icon_Geom *geom)
-{
-	BLI_assert(BLI_thread_is_main());
-
-	if (geom->icon_id) {
-		return geom->icon_id;
-	}
-
-	geom->icon_id = get_next_free_id();
-
-	icon_create(geom->icon_id, ICON_DATA_GEOM, geom);
-	/* Not managed for now, we may want this to be configurable per icon). */
-
-	return geom->icon_id;
-}
-
 Icon *BKE_icon_get(const int icon_id)
 {
 	BLI_assert(BLI_thread_is_main());
@@ -735,3 +726,73 @@ bool BKE_icon_delete_unmanaged(const int icon_id)
 		return false;
 	}
 }
+
+/* -------------------------------------------------------------------- */
+/** \name Geometry Icon
+ * \{ */
+
+int BKE_icon_geom_ensure(struct Icon_Geom *geom)
+{
+	BLI_assert(BLI_thread_is_main());
+
+	if (geom->icon_id) {
+		return geom->icon_id;
+	}
+
+	geom->icon_id = get_next_free_id();
+
+	icon_create(geom->icon_id, ICON_DATA_GEOM, geom);
+	/* Not managed for now, we may want this to be configurable per icon). */
+
+	return geom->icon_id;
+}
+
+struct Icon_Geom *BKE_icon_geom_from_memory(const uchar *data, size_t data_len)
+{
+	BLI_assert(BLI_thread_is_main());
+	if (data_len <= 8) {
+		goto fail;
+	}
+	const int div = 3 * 2 * 3;
+	const int coords_len = (data_len - 8) / div;
+	if (coords_len * div != data_len) {
+		goto fail;
+	}
+
+	const uchar header[4] = {'V', 'C', 'O', 0};
+	const uchar *p = data;
+	if (memcmp(p, header, ARRAY_SIZE(header)) != 0) {
+		goto fail;
+	}
+	p += 4;
+
+	struct Icon_Geom *geom = MEM_mallocN(sizeof(*geom), __func__);
+	geom->coords_range[0] = (int)*p++;
+	geom->coords_range[1] = (int)*p++;
+	/* x, y ignored for now */
+	p += 2;
+
+	geom->coords_len = coords_len;
+	geom->coords = (const void *)p;
+	geom->colors = (const void *)(p + (data_len / 3));
+	geom->icon_id = 0;
+	geom->mem = data;
+	return geom;
+
+fail:
+	MEM_freeN((void *)data);
+	return NULL;
+}
+
+struct Icon_Geom *BKE_icon_geom_from_file(const char *filename)
+{
+	BLI_assert(BLI_thread_is_main());
+	size_t data_len;
+	uchar *data = BLI_file_read_binary_as_mem(filename, 0, &data_len);
+	if (data == NULL) {
+		return NULL;
+	}
+	return BKE_icon_geom_from_memory(data, data_len);
+}
+
+/** \} */
diff --git a/source/blender/python/intern/bpy_app_icons.c b/source/blender/python/intern/bpy_app_icons.c
index 8aeee1aff9c..6d3b50d5688 100644
--- a/source/blender/python/intern/bpy_app_icons.c
+++ b/source/blender/python/intern/bpy_app_icons.c
@@ -38,22 +38,28 @@
 
 /* We may want to load direct from file. */
 PyDoc_STRVAR(bpy_app_icons_new_triangles_doc,
-".. function:: new_triangles(coords, colors)"
+".. function:: new_triangles(range, coords, colors)"
 "\n"
 "   Create a new icon from triangle geometry.\n"
 "\n"
+"   :arg range: Pair of ints.\n"
+"   :type range: tuple.\n"
 "   :arg coords: Sequence of bytes (6 floats for one triangle) for (X, Y) coordinates.\n"
-"   :type coords: byte sequence\n"
+"   :type coords: byte sequence.\n"
 "   :arg colors: Sequence of ints (12 for one triangles) for RGBA.\n"
-"   :type colors: byte sequence\n"
+"   :type colors: byte sequence.\n"
 "   :return: Unique icon value (pass to interface ``icon_value`` argument).\n"
 "   :rtype: int\n"
 );
 static PyObject *bpy_app_icons_new_triangles(PyObject *UNUSED(self), PyObject *args)
 {
 	/* bytes */
+	uchar coords_range[2];
 	PyObject *py_coords, *py_colors;
-	if (!PyArg_ParseTuple(args, "SS:new_triangles", &py_coords, &py_colors)) {
+	if (!PyArg_ParseTuple(
+	            args, "(BB)SS:new_triangles",
+	            &coords_range[0], &coords_range[1], &py_coords, &py_colors))
+	{
 		return NULL;
 	}
 
@@ -78,6 +84,8 @@ static PyObject *bpy_app_icons_new_triangles(PyObject *UNUSED(self), PyObject *a
 
 	struct Icon_Geom *geom = MEM_mallocN(sizeof(*geom), __func__);
 	geom->coords_len = tris_len;
+	geom->coords_range[0] = coords_range[0];
+	geom->coords_range[1] = coords_range[1];
 	geom->coords = coords;
 	geom->colors = colors;
 	geom->icon_id = 0;
@@ -85,6 +93,36 @@ static PyObject *bpy_app_icons_new_triangles(PyObject *UNUSED(self), PyObject *a
 	return PyLong_FromLong(icon_id);
 }
 
+PyDoc_STRVAR(bpy_app_icons_new_triangles_from_file_doc,
+".. function:: new_triangles_from_file(filename)"
+"\n"
+"   Create a new icon from triangle geometry.\n"
+"\n"
+"   :arg range: File path.\n"
+"   :type range: string.\n"
+"   :return: Unique icon value (pass to interface ``icon_value`` argument).\n"
+"   :rtype: int\n"
+);
+static PyObject *bpy_app_icons_new_triangles_from_file(PyObject *UNUSED(self), PyObject *args)
+{
+	/* bytes */
+	char *filename;
+	if (!PyArg_ParseTuple(
+	            args, "s:new_triangles_from_file",
+	            &filename))
+	{
+		return NULL;
+	}
+
+	struct Icon_Geom *geom = BKE_icon_geom_from_file(filename);
+	if (geom == NULL) {
+		PyErr_SetString(PyExc_ValueError, "Unable to load from file");
+		return NULL;
+	}
+	int icon_id = BKE_icon_geom_ensure(geom);
+	return PyLong_FromLong(icon_id);
+}
+
 PyDoc_STRVAR(bpy_app_icons_release_doc,
 ".. function:: release(icon_id)"
 "\n"
@@ -110,6 +148,7 @@ static PyObject *bpy_app_icons_release(PyObject *UNUSED(self), PyObject *args)
 
 static struct PyMethodDef M_AppIcons_methods[] = {
 	{"new_triangles", (PyCFunction)bpy_app_icons_new_triangles, METH_VARARGS, bpy_app_icons_new_triangles_doc},
+	{"new_triangles_from_file", (PyCFunction)bpy_app_icons_new_triangles_from_file, METH_VARARGS, bpy_app_icons_new_triangles_from_file_doc},
 	{"release", (PyCFunction)bpy_app_icons_release, METH_VARARGS, bpy_app_icons_release_doc},
 	{NULL, NULL, 0, NULL}
 };



More information about the Bf-blender-cvs mailing list