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")
This commit is contained in:
Campbell Barton 2012-03-16 05:03:13 +00:00
parent c6c0601d8e
commit ebec111618
7 changed files with 598 additions and 7 deletions

@ -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);

@ -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

@ -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);
}

@ -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__ */

@ -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);

@ -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);

@ -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)
{