From ebec1116184275f594cf08417b04fa43fa554628 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 16 Mar 2012 05:03:13 +0000 Subject: bmesh py api: Wrap customdata, so far you can access the data layers in a pythonic way but not manipulate the customdata yet. provides dictionary like access to customdata layers, eg: texpoly = bm.faces.tex["UVMap"] print(bm.verts.shape.keys()) # un-intended pun, keys() works on all layers. print("MyInt" in bm.edges.int) # __contains__ layer = bm.faces.get("CheckForLayer") --- source/blender/python/bmesh/bmesh_py_api.c | 5 +- source/blender/python/bmesh/bmesh_py_types.c | 46 +- .../python/bmesh/bmesh_py_types_customdata.c | 510 ++++++++++++++++++++- .../python/bmesh/bmesh_py_types_customdata.h | 38 +- .../blender/python/bmesh/bmesh_py_types_select.c | 2 +- .../blender/python/bmesh/bmesh_py_types_select.h | 2 +- source/blender/python/intern/bpy_rna.c | 2 +- 7 files changed, 598 insertions(+), 7 deletions(-) (limited to 'source') diff --git a/source/blender/python/bmesh/bmesh_py_api.c b/source/blender/python/bmesh/bmesh_py_api.c index e3d0455073e..d9ca997bbd5 100644 --- a/source/blender/python/bmesh/bmesh_py_api.c +++ b/source/blender/python/bmesh/bmesh_py_api.c @@ -35,6 +35,8 @@ #include "bmesh_py_types.h" #include "bmesh_py_types_select.h" +#include "bmesh_py_types_customdata.h" + #include "bmesh_py_utils.h" #include "BLI_utildefines.h" @@ -129,7 +131,8 @@ PyObject *BPyInit_bmesh(void) PyObject *sys_modules = PySys_GetObject("modules"); /* not pretty */ BPy_BM_init_types(); - BPy_BM_init_select_types(); + BPy_BM_init_types_select(); + BPy_BM_init_types_customdata(); mod = PyModule_Create(&BPy_BM_module_def); diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index c45ffd38493..d9344c3b690 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -46,6 +46,7 @@ #include "bmesh_py_types.h" /* own include */ #include "bmesh_py_types_select.h" +#include "bmesh_py_types_customdata.h" /* Common Flags * ************ */ @@ -483,6 +484,38 @@ static PyObject *bpy_bmloop_link_loop_prev_get(BPy_BMLoop *self) return BPy_BMLoop_CreatePyObject(self->bm, self->l->prev); } +/* ElemSeq + * ^^^^^^^ */ + +PyDoc_STRVAR(bpy_bmelemseq_layers_doc, +"blah blah (read-only).\n\n:type: :class:`BMLayerAccess`" +); +static PyObject *bpy_bmelemseq_layers_get(BPy_BMElemSeq *self) +{ + char htype; + BPY_BM_CHECK_OBJ(self); + + switch ((BMIterType)self->itype) { + case BM_VERTS_OF_MESH: + htype = BM_VERT; + break; + case BM_EDGES_OF_MESH: + htype = BM_EDGE; + break; + case BM_FACES_OF_MESH: + htype = BM_FACE; + break; + + /* TODO - LOOPS */ + + default: + PyErr_SetString(PyExc_AttributeError, "layers attribute is only valid for vert/edge/face sequences"); + return NULL; + break; + } + + return BPy_BMLayerAccess_CreatePyObject(self->bm, htype); +} static PyGetSetDef bpy_bmesh_getseters[] = { {(char *)"verts", (getter)bpy_bmelemseq_get, (setter)NULL, (char *)bpy_bmesh_verts_doc, (void *)BM_VERTS_OF_MESH}, @@ -592,6 +625,14 @@ static PyGetSetDef bpy_bmloop_getseters[] = { {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; +static PyGetSetDef bpy_bmelemseq_getseters[] = { + {(char *)"layers", (getter)bpy_bmelemseq_layers_get, (setter)NULL, (char *)bpy_bmelemseq_layers_doc, NULL}, + + {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ +}; + + + /* Methods * ======= */ @@ -2549,7 +2590,7 @@ void BPy_BM_init_types(void) BPy_BMEdge_Type.tp_getset = bpy_bmedge_getseters; BPy_BMFace_Type.tp_getset = bpy_bmface_getseters; BPy_BMLoop_Type.tp_getset = bpy_bmloop_getseters; - BPy_BMElemSeq_Type.tp_getset = NULL; + BPy_BMElemSeq_Type.tp_getset = bpy_bmelemseq_getseters; BPy_BMIter_Type.tp_getset = NULL; @@ -2649,6 +2690,9 @@ PyObject *BPyInit_bmesh_types(void) mod_type_add(submodule, BPy_BMIter_Type); mod_type_add(submodule, BPy_BMEditSelSeq_Type); mod_type_add(submodule, BPy_BMEditSelIter_Type); + mod_type_add(submodule, BPy_BMLayerAccess_Type); + mod_type_add(submodule, BPy_BMLayerCollection_Type); + mod_type_add(submodule, BPy_BMLayerItem_Type); #undef mod_type_add diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.c b/source/blender/python/bmesh/bmesh_py_types_customdata.c index d9b2eb37534..4b53b6e11d0 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.c +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.c @@ -35,5 +35,513 @@ #include "bmesh.h" #include "bmesh_py_types.h" +#include "bmesh_py_types_customdata.h" -/* TODO */ +#include "BKE_customdata.h" + +static CustomData *bpy_bm_customdata_get(BMesh *bm, char htype) +{ + switch (htype) { + case BM_VERT: return &bm->vdata; + case BM_EDGE: return &bm->edata; + case BM_FACE: return &bm->pdata; + case BM_LOOP: return &bm->ldata; + } + + BLI_assert(0); + return NULL; +} + +static CustomDataLayer *bpy_bmlayeritem_get(BPy_BMLayerItem *self) +{ + CustomData *data = bpy_bm_customdata_get(self->bm, self->htype); + return &data->layers[CustomData_get_layer_index_n(data, self->type, self->index)]; +} + +/* py-type definitions + * ******************* */ + +/* getseters + * ========= */ + +static PyObject *bpy_bmlayeraccess_collection_get(BPy_BMLayerAccess *self, void *flag) +{ + const int type = (int)GET_INT_FROM_POINTER(flag); + + BPY_BM_CHECK_OBJ(self); + + return BPy_BMLayerCollection_CreatePyObject(self->bm, self->htype, type); +} + +static PyObject *bpy_bmlayeritem_name_get(BPy_BMLayerItem *self, void *UNUSED(flag)) +{ + CustomDataLayer *layer; + + BPY_BM_CHECK_OBJ(self); + + layer = bpy_bmlayeritem_get(self); + return PyUnicode_FromString(layer->name); +} + +static PyGetSetDef bpy_bmlayeraccess_getseters[] = { + {(char *)"deform", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_MDEFORMVERT}, + + {(char *)"float", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_PROP_FLT}, + {(char *)"int", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_PROP_INT}, + {(char *)"string", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_PROP_STR}, + + {(char *)"tex", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_MTEXPOLY}, + {(char *)"uv", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_MLOOPUV}, + {(char *)"color", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_MLOOPCOL}, + + {(char *)"shape", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_SHAPEKEY}, + {(char *)"bevel_weight", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_SHAPEKEY}, + {(char *)"crease", (getter)bpy_bmlayeraccess_collection_get, (setter)NULL, (char *)NULL, (void *)CD_CREASE}, + + {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ +}; + +static PyGetSetDef bpy_bmlayeritem_getseters[] = { + /* BMESH_TODO, make writeable */ + {(char *)"name", (getter)bpy_bmlayeritem_name_get, (setter)NULL, (char *)NULL, NULL}, + + {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ +}; + + +/* Methods + * ======= */ + +/* BMLayerCollection + * ----------------- */ + +PyDoc_STRVAR(bpy_bmlayercollection_keys_doc, +".. method:: keys()\n" +"\n" +" Return the identifiers of collection members\n" +" (matching pythons dict.keys() functionality).\n" +"\n" +" :return: the identifiers for each member of this collection.\n" +" :rtype: list of strings\n" +); +static PyObject *bpy_bmlayercollection_keys(BPy_BMLayerCollection *self) +{ + PyObject *ret = PyList_New(0); + PyObject *item; + int index; + CustomData *data; + + BPY_BM_CHECK_OBJ(self); + + data = bpy_bm_customdata_get(self->bm, self->htype); + index = CustomData_get_layer_index(data, self->type); + + ret = PyList_New(0); + + if (index != -1) { + int tot = CustomData_number_of_layers(data, self->type); + for ( ; tot-- > 0; index++) { + item = PyUnicode_FromString(data->layers[index].name); + PyList_Append(ret, item); + Py_DECREF(item); + } + } + + return ret; +} + +PyDoc_STRVAR(bpy_bmlayercollection_values_doc, +".. method:: items()\n" +"\n" +" Return the identifiers of collection members\n" +" (matching pythons dict.items() functionality).\n" +"\n" +" :return: (key, value) pairs for each member of this collection.\n" +" :rtype: list of tuples\n" +); +static PyObject *bpy_bmlayercollection_values(BPy_BMLayerCollection *self) +{ + PyObject *ret; + PyObject *item; + int index; + CustomData *data; + + BPY_BM_CHECK_OBJ(self); + + data = bpy_bm_customdata_get(self->bm, self->htype); + index = CustomData_get_layer_index(data, self->type); + + ret = PyList_New(0); + + if (index != -1) { + int tot = CustomData_number_of_layers(data, self->type); + for ( ; tot-- > 0; index++) { + item = PyTuple_New(2); + PyTuple_SET_ITEM(item, 0, PyUnicode_FromString(data->layers[index].name)); + PyTuple_SET_ITEM(item, 1, BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index)); + PyList_Append(ret, item); + Py_DECREF(item); + } + } + + return ret; +} + +PyDoc_STRVAR(bpy_bmlayercollection_items_doc, +".. method:: values()\n" +"\n" +" Return the values of collection\n" +" (matching pythons dict.values() functionality).\n" +"\n" +" :return: the members of this collection.\n" +" :rtype: list\n" +); +static PyObject *bpy_bmlayercollection_items(BPy_BMLayerCollection *self) +{ + PyObject *ret; + PyObject *item; + int index; + CustomData *data; + + BPY_BM_CHECK_OBJ(self); + + data = bpy_bm_customdata_get(self->bm, self->htype); + index = CustomData_get_layer_index(data, self->type); + + ret = PyList_New(0); + + if (index != -1) { + int tot = CustomData_number_of_layers(data, self->type); + for ( ; tot-- > 0; index++) { + item = BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index); + PyList_Append(ret, item); + Py_DECREF(item); + } + } + + return ret; +} + +PyDoc_STRVAR(bpy_bmlayercollection_get_doc, +".. method:: get(key, default=None)\n" +"\n" +" Returns the value of the layer matching the key or default\n" +" when not found (matches pythons dictionary function of the same name).\n" +"\n" +" :arg key: The key associated with the layer.\n" +" :type key: string\n" +" :arg default: Optional argument for the value to return if\n" +" *key* is not found.\n" +" :type default: Undefined\n" +); +static PyObject *bpy_bmlayercollection_get(BPy_BMLayerCollection *self, PyObject *args) +{ + const char *key; + PyObject* def = Py_None; + + BPY_BM_CHECK_OBJ(self); + + if (!PyArg_ParseTuple(args, "s|O:get", &key, &def)) { + return NULL; + } + else { + CustomData *data; + int index; + + data = bpy_bm_customdata_get(self->bm, self->htype); + index = CustomData_get_named_layer_index(data, self->type, key); + + if (index != -1) { + return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index); + } + } + + return Py_INCREF(def), def; +} + +static struct PyMethodDef bpy_bmelemseq_methods[] = { + {"keys", (PyCFunction)bpy_bmlayercollection_keys, METH_NOARGS, bpy_bmlayercollection_keys_doc}, + {"values", (PyCFunction)bpy_bmlayercollection_values, METH_NOARGS, bpy_bmlayercollection_values_doc}, + {"items", (PyCFunction)bpy_bmlayercollection_items, METH_NOARGS, bpy_bmlayercollection_items_doc}, + {"get", (PyCFunction)bpy_bmlayercollection_get, METH_VARARGS, bpy_bmlayercollection_get_doc}, + + /* for later! */ +#if 0 + + {"new", (PyCFunction)bpy_bmlayercollection_new, METH_O, bpy_bmlayercollection_new_doc}, + {"remove", (PyCFunction)bpy_bmlayercollection_new, METH_O, bpy_bmlayercollection_remove_doc}, +#endif + {NULL, NULL, 0, NULL} +}; + + + +/* Sequences + * ========= */ + +static Py_ssize_t bpy_bmlayercollection_length(BPy_BMLayerCollection *self) +{ + CustomData *data; + + BPY_BM_CHECK_INT(self); + + data = bpy_bm_customdata_get(self->bm, self->htype); + + return CustomData_number_of_layers(data, self->type); +} + +static PyObject *bpy_bmlayercollection_subscript_str(BPy_BMLayerCollection *self, const char *keyname) +{ + CustomData *data; + int index; + + BPY_BM_CHECK_OBJ(self); + + data = bpy_bm_customdata_get(self->bm, self->htype); + index = CustomData_get_named_layer_index(data, self->type, keyname); + + if (index != -1) { + return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, index); + } + else { + PyErr_Format(PyExc_KeyError, + "BMLayerCollection[key]: key \"%.200s\" not found", keyname); + return NULL; + } +} + +static PyObject *bpy_bmlayercollection_subscript_int(BPy_BMLayerCollection *self, int keynum) +{ + Py_ssize_t len; + BPY_BM_CHECK_OBJ(self); + + len = bpy_bmlayercollection_length(self); + + if (keynum < 0) keynum += len; + if (keynum >= 0) { + if (keynum < len) { + return BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, keynum); + } + } + + PyErr_Format(PyExc_IndexError, + "BMLayerCollection[index]: index %d out of range", keynum); + return NULL; +} + +static PyObject *bpy_bmlayercollection_subscript_slice(BPy_BMLayerCollection *self, Py_ssize_t start, Py_ssize_t stop) +{ + Py_ssize_t len = bpy_bmlayercollection_length(self); + int count = 0; + + PyObject *tuple; + + BPY_BM_CHECK_OBJ(self); + + if (start >= start) start = len - 1; + if (stop >= stop) stop = len - 1; + + tuple = PyTuple_New(stop - start); + + for (count = start; count < stop; count++) { + PyTuple_SET_ITEM(tuple, count - start, BPy_BMLayerItem_CreatePyObject(self->bm, self->htype, self->type, count)); + } + + return tuple; +} + +static PyObject *bpy_bmlayercollection_subscript(BPy_BMLayerCollection *self, PyObject *key) +{ + /* dont need error check here */ + if (PyUnicode_Check(key)) { + return bpy_bmlayercollection_subscript_str(self, _PyUnicode_AsString(key)); + } + else if (PyIndex_Check(key)) { + Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError); + if (i == -1 && PyErr_Occurred()) + return NULL; + return bpy_bmlayercollection_subscript_int(self, i); + } + else if (PySlice_Check(key)) { + PySliceObject *key_slice = (PySliceObject *)key; + Py_ssize_t step = 1; + + if (key_slice->step != Py_None && !_PyEval_SliceIndex(key, &step)) { + return NULL; + } + else if (step != 1) { + PyErr_SetString(PyExc_TypeError, + "BMLayerCollection[slice]: slice steps not supported"); + return NULL; + } + else if (key_slice->start == Py_None && key_slice->stop == Py_None) { + return bpy_bmlayercollection_subscript_slice(self, 0, PY_SSIZE_T_MAX); + } + else { + Py_ssize_t start = 0, stop = PY_SSIZE_T_MAX; + + /* avoid PySlice_GetIndicesEx because it needs to know the length ahead of time. */ + if (key_slice->start != Py_None && !_PyEval_SliceIndex(key_slice->start, &start)) return NULL; + if (key_slice->stop != Py_None && !_PyEval_SliceIndex(key_slice->stop, &stop)) return NULL; + + if (start < 0 || stop < 0) { + /* only get the length for negative values */ + Py_ssize_t len = bpy_bmlayercollection_length(self); + if (start < 0) start += len; + if (stop < 0) start += len; + } + + if (stop - start <= 0) { + return PyTuple_New(0); + } + else { + return bpy_bmlayercollection_subscript_slice(self, start, stop); + } + } + } + else { + PyErr_SetString(PyExc_AttributeError, + "BMLayerCollection[key]: invalid key, key must be an int"); + return NULL; + } +} + +static int bpy_bmlayercollection_contains(BPy_BMLayerCollection *self, PyObject *value) +{ + const char *keyname = _PyUnicode_AsString(value); + CustomData *data; + int index; + + BPY_BM_CHECK_INT(self); + + if (keyname == NULL) { + PyErr_SetString(PyExc_TypeError, + "BMLayerCollection.__contains__: expected a string"); + return -1; + } + + data = bpy_bm_customdata_get(self->bm, self->htype); + index = CustomData_get_named_layer_index(data, self->type, keyname); + + return (index != -1) ? 1 : 0; +} + +static PySequenceMethods bpy_bmlayercollection_as_sequence = { + (lenfunc)bpy_bmlayercollection_length, /* sq_length */ + NULL, /* sq_concat */ + NULL, /* sq_repeat */ + (ssizeargfunc)bpy_bmlayercollection_subscript_int, /* sq_item */ /* Only set this so PySequence_Check() returns True */ + NULL, /* sq_slice */ + (ssizeobjargproc)NULL, /* sq_ass_item */ + NULL, /* *was* sq_ass_slice */ + (objobjproc)bpy_bmlayercollection_contains, /* sq_contains */ + (binaryfunc) NULL, /* sq_inplace_concat */ + (ssizeargfunc) NULL, /* sq_inplace_repeat */ +}; + +static PyMappingMethods bpy_bmlayercollection_as_mapping = { + (lenfunc)bpy_bmlayercollection_length, /* mp_length */ + (binaryfunc)bpy_bmlayercollection_subscript, /* mp_subscript */ + (objobjargproc)NULL, /* mp_ass_subscript */ +}; + +/* Iterator + * -------- */ + +static PyObject *bpy_bmlayercollection_iter(BPy_BMLayerCollection *self) +{ + /* fake it with a list iterator */ + PyObject *ret; + PyObject *iter = NULL; + + BPY_BM_CHECK_OBJ(self); + + ret = bpy_bmlayercollection_subscript_slice(self, 0, PY_SSIZE_T_MIN); + + if (ret) { + iter = PyObject_GetIter(ret); + Py_DECREF(ret); + } + + return iter; +} + +PyTypeObject BPy_BMLayerAccess_Type = {{{0}}}; /* bm.verts.layers */ +PyTypeObject BPy_BMLayerCollection_Type = {{{0}}}; /* bm.verts.layers.uv */ +PyTypeObject BPy_BMLayerItem_Type = {{{0}}}; /* bm.verts.layers.uv["UVMap"] */ + + +PyObject *BPy_BMLayerAccess_CreatePyObject(BMesh *bm, const char htype) +{ + BPy_BMLayerAccess *self = PyObject_New(BPy_BMLayerAccess, &BPy_BMLayerAccess_Type); + self->bm = bm; + self->htype = htype; + return (PyObject *)self; +} + +PyObject *BPy_BMLayerCollection_CreatePyObject(BMesh *bm, const char htype, int type) +{ + BPy_BMLayerCollection *self = PyObject_New(BPy_BMLayerCollection, &BPy_BMLayerCollection_Type); + self->bm = bm; + self->htype = htype; + self->type = type; + return (PyObject *)self; +} + +PyObject *BPy_BMLayerItem_CreatePyObject(BMesh *bm, const char htype, int type, int index) +{ + BPy_BMLayerItem *self = PyObject_New(BPy_BMLayerItem, &BPy_BMLayerItem_Type); + self->bm = bm; + self->htype = htype; + self->type = type; + self->index = index; + return (PyObject *)self; +} + + +void BPy_BM_init_types_customdata(void) +{ + BPy_BMLayerAccess_Type.tp_basicsize = sizeof(BPy_BMLayerAccess); + BPy_BMLayerCollection_Type.tp_basicsize = sizeof(BPy_BMLayerCollection); + BPy_BMLayerItem_Type.tp_basicsize = sizeof(BPy_BMLayerItem); + + BPy_BMLayerAccess_Type.tp_name = "BMLayerAccess"; + BPy_BMLayerCollection_Type.tp_name = "BMLayerCollection"; + BPy_BMLayerItem_Type.tp_name = "BMLayerItem"; + + BPy_BMLayerAccess_Type.tp_doc = NULL; // todo + BPy_BMLayerCollection_Type.tp_doc = NULL; + BPy_BMLayerItem_Type.tp_doc = NULL; + + BPy_BMLayerAccess_Type.tp_repr = (reprfunc)NULL; + BPy_BMLayerCollection_Type.tp_repr = (reprfunc)NULL; + BPy_BMLayerItem_Type.tp_repr = (reprfunc)NULL; + + BPy_BMLayerAccess_Type.tp_getset = bpy_bmlayeraccess_getseters; + BPy_BMLayerCollection_Type.tp_getset = NULL; + BPy_BMLayerItem_Type.tp_getset = bpy_bmlayeritem_getseters; + + +// BPy_BMLayerAccess_Type.tp_methods = bpy_bmeditselseq_methods; + BPy_BMLayerCollection_Type.tp_methods = bpy_bmelemseq_methods; + + BPy_BMLayerCollection_Type.tp_as_sequence = &bpy_bmlayercollection_as_sequence; + + BPy_BMLayerCollection_Type.tp_as_mapping = &bpy_bmlayercollection_as_mapping; + + BPy_BMLayerCollection_Type.tp_iter = (getiterfunc)bpy_bmlayercollection_iter; + + BPy_BMLayerAccess_Type.tp_dealloc = NULL; //(destructor)bpy_bmeditselseq_dealloc; + BPy_BMLayerCollection_Type.tp_dealloc = NULL; //(destructor)bpy_bmvert_dealloc; + BPy_BMLayerItem_Type.tp_dealloc = NULL; //(destructor)bpy_bmvert_dealloc; + + + + BPy_BMLayerAccess_Type.tp_flags = Py_TPFLAGS_DEFAULT; + BPy_BMLayerCollection_Type.tp_flags = Py_TPFLAGS_DEFAULT; + BPy_BMLayerItem_Type.tp_flags = Py_TPFLAGS_DEFAULT; + + PyType_Ready(&BPy_BMLayerAccess_Type); + PyType_Ready(&BPy_BMLayerCollection_Type); + PyType_Ready(&BPy_BMLayerItem_Type); +} diff --git a/source/blender/python/bmesh/bmesh_py_types_customdata.h b/source/blender/python/bmesh/bmesh_py_types_customdata.h index 07dafc63dee..0de79d7bd21 100644 --- a/source/blender/python/bmesh/bmesh_py_types_customdata.h +++ b/source/blender/python/bmesh/bmesh_py_types_customdata.h @@ -30,6 +30,42 @@ #ifndef __BMESH_PY_TYPES_CUSTOMDATA_H__ #define __BMESH_PY_TYPES_CUSTOMDATA_H__ -/* TODO */ +extern PyTypeObject BPy_BMLayerAccess_Type; +extern PyTypeObject BPy_BMLayerCollection_Type; +extern PyTypeObject BPy_BMLayerItem_Type; + +#define BPy_BMLayerAccess_Check(v) (Py_TYPE(v) == &BPy_BMLayerAccess_Type) +#define BPy_BMLayerCollection_Check(v) (Py_TYPE(v) == &BPy_BMLayerCollection_Type) +#define BPy_BMLayerItem_Check(v) (Py_TYPE(v) == &BPy_BMLayerItem_Type) + +/* all layers for vert/edge/face/loop */ +typedef struct BPy_BMLayerAccess { + PyObject_VAR_HEAD + struct BMesh *bm; /* keep first */ + char htype; +} BPy_BMLayerAccess; + +/* access different layer types deform/uv/vertexcolor */ +typedef struct BPy_BMLayerCollection { + PyObject_VAR_HEAD + struct BMesh *bm; /* keep first */ + char htype; + int type; /* customdata type - CD_XXX */ +} BPy_BMLayerCollection; + +/* access a spesific layer directly */ +typedef struct BPy_BMLayerItem { + PyObject_VAR_HEAD + struct BMesh *bm; /* keep first */ + char htype; + int type; /* customdata type - CD_XXX */ + int index; /* index of this layer type */ +} BPy_BMLayerItem; + +PyObject *BPy_BMLayerAccess_CreatePyObject(BMesh *bm, const char htype); +PyObject *BPy_BMLayerCollection_CreatePyObject(BMesh *bm, const char htype, int type); +PyObject *BPy_BMLayerItem_CreatePyObject(BMesh *bm, const char htype, int type, int index); + +void BPy_BM_init_types_customdata(void); #endif /* __BMESH_PY_TYPES_CUSTOMDATA_H__ */ diff --git a/source/blender/python/bmesh/bmesh_py_types_select.c b/source/blender/python/bmesh/bmesh_py_types_select.c index fb9ec6437ae..4bd8ce70fbc 100644 --- a/source/blender/python/bmesh/bmesh_py_types_select.c +++ b/source/blender/python/bmesh/bmesh_py_types_select.c @@ -379,7 +379,7 @@ PyObject *BPy_BMEditSelIter_CreatePyObject(BMesh *bm) return (PyObject *)self; } -void BPy_BM_init_select_types(void) +void BPy_BM_init_types_select(void) { BPy_BMEditSelSeq_Type.tp_basicsize = sizeof(BPy_BMEditSelSeq); BPy_BMEditSelIter_Type.tp_basicsize = sizeof(BPy_BMEditSelIter); diff --git a/source/blender/python/bmesh/bmesh_py_types_select.h b/source/blender/python/bmesh/bmesh_py_types_select.h index 13d4fc6ce03..4741e229400 100644 --- a/source/blender/python/bmesh/bmesh_py_types_select.h +++ b/source/blender/python/bmesh/bmesh_py_types_select.h @@ -49,7 +49,7 @@ typedef struct BPy_BMEditSelIter { struct BMEditSelection *ese; } BPy_BMEditSelIter; -void BPy_BM_init_select_types(void); +void BPy_BM_init_types_select(void); PyObject *BPy_BMEditSel_CreatePyObject(BMesh *bm); PyObject *BPy_BMEditSelIter_CreatePyObject(BMesh *bm); diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index 1af1f8fc9e4..56c892c7d9f 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -3927,7 +3927,7 @@ PyDoc_STRVAR(pyrna_prop_collection_keys_doc, " (matching pythons dict.keys() functionality).\n" "\n" " :return: the identifiers for each member of this collection.\n" -" :rtype: list of stings\n" +" :rtype: list of strings\n" ); static PyObject *pyrna_prop_collection_keys(BPy_PropertyRNA *self) { -- cgit v1.2.3