[Bf-blender-cvs] [564d37c4b67] blender2.8: Python API: new GPUVertFormat constructor and vbo.fill_attribute method

Jacques Lucke noreply at git.blender.org
Fri Oct 5 15:13:03 CEST 2018


Commit: 564d37c4b67af534b6c12d2bebbd7883c3d3817c
Author: Jacques Lucke
Date:   Fri Oct 5 15:10:56 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB564d37c4b67af534b6c12d2bebbd7883c3d3817c

Python API: new GPUVertFormat constructor and vbo.fill_attribute method

Reviewer: fclem

Differential Revision: https://developer.blender.org/D3760

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

M	source/blender/gpu/GPU_vertex_format.h
M	source/blender/gpu/intern/gpu_vertex_format.c
M	source/blender/python/gpu/gpu_py_vertex_buffer.c
M	source/blender/python/gpu/gpu_py_vertex_format.c

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

diff --git a/source/blender/gpu/GPU_vertex_format.h b/source/blender/gpu/GPU_vertex_format.h
index 7e0038e3473..5e7e036bf41 100644
--- a/source/blender/gpu/GPU_vertex_format.h
+++ b/source/blender/gpu/GPU_vertex_format.h
@@ -87,6 +87,7 @@ uint GPU_vertformat_attr_add(
         GPUVertFormat *, const char *name,
         GPUVertCompType, uint comp_len, GPUVertFetchMode);
 void GPU_vertformat_alias_add(GPUVertFormat *, const char *alias);
+int GPU_vertformat_attr_id_get(const GPUVertFormat *, const char *name);
 
 /* format conversion */
 
diff --git a/source/blender/gpu/intern/gpu_vertex_format.c b/source/blender/gpu/intern/gpu_vertex_format.c
index 59e413a1f3e..f1aaa99fbc6 100644
--- a/source/blender/gpu/intern/gpu_vertex_format.c
+++ b/source/blender/gpu/intern/gpu_vertex_format.c
@@ -34,6 +34,8 @@
 #include <stddef.h>
 #include <string.h>
 
+#include "BLI_utildefines.h"
+
 #define PACK_DEBUG 0
 
 #if PACK_DEBUG
@@ -204,6 +206,19 @@ void GPU_vertformat_alias_add(GPUVertFormat *format, const char *alias)
 	attrib->name[attrib->name_len++] = copy_attrib_name(format, alias);
 }
 
+int GPU_vertformat_attr_id_get(const GPUVertFormat *format, const char *name)
+{
+	for (int i = 0; i < format->attr_len; i++) {
+		const GPUVertAttr *attrib = format->attribs + i;
+		for (int j = 0; j < attrib->name_len; j++) {
+			if (STREQ(name, attrib->name[j])) {
+				return i;
+			}
+		}
+	}
+	return -1;
+}
+
 uint padding(uint offset, uint alignment)
 {
 	const uint mod = offset % alignment;
diff --git a/source/blender/python/gpu/gpu_py_vertex_buffer.c b/source/blender/python/gpu/gpu_py_vertex_buffer.c
index 53fbbf623fa..fd4ee64c996 100644
--- a/source/blender/python/gpu/gpu_py_vertex_buffer.c
+++ b/source/blender/python/gpu/gpu_py_vertex_buffer.c
@@ -188,20 +188,28 @@ finally:
 	return ok;
 }
 
-/* handy, but not used just now */
-#if 0
-static int bpygpu_find_id(const GPUVertFormat *fmt, const char *id)
+static int bpygpu_fill_attribute(GPUVertBuf *buf, int id, PyObject *py_seq_data)
 {
-	for (int i = 0; i < fmt->attr_len; i++) {
-		for (uint j = 0; j < fmt->name_len; j++) {
-			if (STREQ(fmt->attribs[i].name[j], id)) {
-				return i;
-			}
-		}
+	if (id < 0 || id >= buf->format.attr_len) {
+		PyErr_Format(PyExc_ValueError,
+		             "Format id %d out of range",
+		             id);
+		return 0;
+	}
+
+	if (buf->data == NULL) {
+		PyErr_SetString(PyExc_ValueError,
+		                "Can't fill, static buffer already in use");
+		return 0;
 	}
-	return -1;
+
+	if (!bpygpu_vertbuf_fill_impl(buf, (uint)id, py_seq_data)) {
+		return 0;
+	}
+
+	return 1;
 }
-#endif
+
 
 /** \} */
 
@@ -218,12 +226,12 @@ static PyObject *bpygpu_VertBuf_new(PyTypeObject *UNUSED(type), PyObject *args,
 		uint len;
 	} params;
 
-	static const char *_keywords[] = {"len", "format", NULL};
-	static _PyArg_Parser _parser = {"$IO!:GPUVertBuf.__new__", _keywords, 0};
+	static const char *_keywords[] = {"format", "len", NULL};
+	static _PyArg_Parser _parser = {"O!I:GPUVertBuf.__new__", _keywords, 0};
 	if (!_PyArg_ParseTupleAndKeywordsFast(
 	        args, kwds, &_parser,
-	        &params.len,
-	        &BPyGPUVertFormat_Type, &params.py_fmt))
+	        &BPyGPUVertFormat_Type, &params.py_fmt,
+	        &params.len))
 	{
 		return NULL;
 	}
@@ -235,48 +243,62 @@ static PyObject *bpygpu_VertBuf_new(PyTypeObject *UNUSED(type), PyObject *args,
 	return BPyGPUVertBuf_CreatePyObject(vbo);
 }
 
-PyDoc_STRVAR(bpygpu_VertBuf_fill_doc,
-"TODO"
+PyDoc_STRVAR(bpygpu_VertBuf_fill_attribute_doc,
+"fill_attribute(identifier, data)\n"
+"\n"
+"   Insert data into the buffer for a single attribute.\n"
+"\n"
+"   :param identifier: Either the name or the id of the attribute.\n"
+"   :type identifier: int or str\n"
+"   :param data: Sequence of data that should be stored in the buffer\n"
+"   :type data: sequence of individual values or tuples\n"
 );
-static PyObject *bpygpu_VertBuf_fill(BPyGPUVertBuf *self, PyObject *args, PyObject *kwds)
+static PyObject *bpygpu_VertBuf_fill_attribute(BPyGPUVertBuf *self, PyObject *args, PyObject *kwds)
 {
-	struct {
-		uint id;
-		PyObject *py_seq_data;
-	} params;
+	PyObject *data;
+	PyObject *identifier;
 
-	static const char *_keywords[] = {"id", "data", NULL};
-	static _PyArg_Parser _parser = {"$IO:fill", _keywords, 0};
+	static const char *_keywords[] = {"identifier", "data", NULL};
+	static _PyArg_Parser _parser = {"OO:fill_attribute", _keywords, 0};
 	if (!_PyArg_ParseTupleAndKeywordsFast(
 	        args, kwds, &_parser,
-	        &params.id,
-	        &params.py_seq_data))
+	        &identifier, &data))
 	{
 		return NULL;
 	}
 
-	if (params.id >= self->buf->format.attr_len) {
-		PyErr_Format(PyExc_ValueError,
-		             "Format id %d out of range",
-		             params.id);
-		return NULL;
-	}
+	int id;
 
-	if (self->buf->data == NULL) {
-		PyErr_SetString(PyExc_ValueError,
-		                "Can't fill, static buffer already in use");
+	if (PyLong_Check(identifier)) {
+		id = PyLong_AsLong(identifier);
+	}
+	else if (PyUnicode_Check(identifier)) {
+		const char *name = PyUnicode_AsUTF8(identifier);
+		id = GPU_vertformat_attr_id_get(&self->buf->format, name);
+		if (id == -1) {
+			PyErr_SetString(PyExc_ValueError,
+			                "Unknown attribute name");
+			return NULL;
+		}
+	}
+	else {
+		PyErr_SetString(PyExc_TypeError,
+		                "expected int or str type as identifier");
 		return NULL;
 	}
 
-	if (!bpygpu_vertbuf_fill_impl(self->buf, params.id, params.py_seq_data)) {
+
+	if (!bpygpu_fill_attribute(self->buf, id, data)) {
 		return NULL;
 	}
+
 	Py_RETURN_NONE;
 }
 
+
 static struct PyMethodDef bpygpu_VertBuf_methods[] = {
-	{"fill", (PyCFunction) bpygpu_VertBuf_fill,
-	 METH_VARARGS | METH_KEYWORDS, bpygpu_VertBuf_fill_doc},
+	{"fill_attribute", (PyCFunction) bpygpu_VertBuf_fill_attribute,
+	 METH_VARARGS | METH_KEYWORDS, bpygpu_VertBuf_fill_attribute_doc},
 	{NULL, NULL, 0, NULL}
 };
 
diff --git a/source/blender/python/gpu/gpu_py_vertex_format.c b/source/blender/python/gpu/gpu_py_vertex_format.c
index 34f6af75477..794167fab7a 100644
--- a/source/blender/python/gpu/gpu_py_vertex_format.c
+++ b/source/blender/python/gpu/gpu_py_vertex_format.c
@@ -55,79 +55,104 @@
  * Use with PyArg_ParseTuple's "O&" formatting.
  * \{ */
 
+static int bpygpu_parse_component_type(const char *str, int length)
+{
+	if (length == 2) {
+		switch (*((ushort *)str)) {
+			case MAKE_ID2('I', '8'): return GPU_COMP_I8;
+			case MAKE_ID2('U', '8'): return GPU_COMP_U8;
+			default: break;
+		}
+	}
+	else if (length == 3) {
+		switch (*((uint *)str)) {
+			case MAKE_ID3('I', '1', '6'): return GPU_COMP_I16;
+			case MAKE_ID3('U', '1', '6'): return GPU_COMP_U16;
+			case MAKE_ID3('I', '3', '2'): return GPU_COMP_I32;
+			case MAKE_ID3('U', '3', '2'): return GPU_COMP_U32;
+			case MAKE_ID3('F', '3', '2'): return GPU_COMP_F32;
+			case MAKE_ID3('I', '1', '0'): return GPU_COMP_I10;
+			default: break;
+		}
+	}
+	return -1;
+}
+
+static int bpygpu_parse_fetch_mode(const char *str, int length)
+{
+#define MATCH_ID(id) \
+	if (length == strlen(STRINGIFY(id))) { \
+		if (STREQ(str, STRINGIFY(id))) { \
+			return GPU_FETCH_##id; \
+		} \
+	} ((void)0)
+
+	MATCH_ID(FLOAT);
+	MATCH_ID(INT);
+	MATCH_ID(INT_TO_FLOAT_UNIT);
+	MATCH_ID(INT_TO_FLOAT);
+#undef MATCH_ID
+
+	return -1;
+}
+
 static int bpygpu_ParseVertCompType(PyObject *o, void *p)
 {
-	Py_ssize_t comp_type_id_len;
-	const char *comp_type_id = _PyUnicode_AsStringAndSize(o, &comp_type_id_len);
-	if (comp_type_id == NULL) {
+	Py_ssize_t length;
+	const char *str = _PyUnicode_AsStringAndSize(o, &length);
+
+	if (str == NULL) {
 		PyErr_Format(PyExc_ValueError,
 		             "expected a string, got %s",
 		             Py_TYPE(o)->tp_name);
 		return 0;
 	}
 
-	GPUVertCompType comp_type;
-	if (comp_type_id_len == 2) {
-		switch (*((ushort *)comp_type_id)) {
-			case MAKE_ID2('I', '8'): { comp_type = GPU_COMP_I8; goto success; }
-			case MAKE_ID2('U', '8'): { comp_type = GPU_COMP_U8; goto success; }
-		}
-	}
-	else if (comp_type_id_len == 3) {
-		switch (*((uint *)comp_type_id)) {
-			case MAKE_ID3('I', '1', '6'): { comp_type = GPU_COMP_I16; goto success; }
-			case MAKE_ID3('U', '1', '6'): { comp_type = GPU_COMP_U16; goto success; }
-			case MAKE_ID3('I', '3', '2'): { comp_type = GPU_COMP_I32; goto success; }
-			case MAKE_ID3('U', '3', '2'): { comp_type = GPU_COMP_U32; goto success; }
-			case MAKE_ID3('F', '3', '2'): { comp_type = GPU_COMP_F32; goto success; }
-			case MAKE_ID3('I', '1', '0'): { comp_type = GPU_COMP_I10; goto success; }
-		}
+	int comp_type = bpygpu_parse_component_type(str, length);
+	if (comp_type == -1) {
+		PyErr_Format(PyExc_ValueError,
+		             "unkown component type: '%s",
+		             str);
+		return 0;
 	}
 
-	PyErr_Format(PyExc_ValueError,
-	             "unknown type literal: '%s'",
-	             comp_type_id);
-	return 0;
-
-success:
 	*((GPUVertCompType *)p) = comp_type;
 	return 1;
 }
 
 static int bpygpu_ParseVertFetchMode(PyObject *o, void *p)
 {
-	Py_ssize_t mode_id_len;
-	const char *mode_id = _PyUnicode_AsStringAndSize(o, &mode_id_len);
-	if (mode_id == NULL) {
+	Py_ssize_t length;
+	const char *str = _PyUnicode_AsStringAndSize(o, &length);
+
+	if (str == NULL) {
 		PyErr_Format(PyExc_ValueError,
 		             "expected a string, got %s",
 		             Py_TYPE(o)->tp_name);
 		return 0;
 	}
-#define MATCH_ID(id) \
-	if (mode_id_len == strlen(STRINGIFY(id))) { \
-		if (STREQ(mode_id, STRINGIFY(id))) { \
-			mode = GPU_FETCH_##id; \
-			goto success; \
-		} \
-	} ((void)0)
 
-	GPUVertFetchMode mode;
-	MATCH_ID(FLOAT);
-	MATCH_ID(INT);
-	MATCH_ID(INT_TO_FLOAT_UNIT);
-	MATCH_ID(INT_TO_FLOAT);
-#undef MATCH_ID
-	PyErr_Format(PyExc_ValueError,
-	             "unknown type literal: '%s'",
-	             mode_id);
-	return 0;
+	int fetch_mode = bpygpu_parse_fetch_mode(str, length);
+	if (fetch_mode == -1) {
+		PyErr_Format(PyExc_ValueError,
+		             "unknown type literal: '%s'",
+		             str);
+		return 0;
+	}
 
-success:
-	(*(GPUVertFetchMode *)p) = mode;
+	(*(GPUVertFetchMode *)p) = fetch_mode;
 	return 1;
 }
 
+static int get_default_fetch_mode(GPUVertCompType type)
+{
+	switch (type)
+	{
+	case GPU_COMP_F32: return GPU_FETCH_FLOAT;
+	default: return -1;

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list