added API function to C and python

* C:  BM_vert_separate(...)
* py: bmesh.utils.vert_separate(vert, edges)

This splits off regions around the vertex, splitting on connected edges passed in a sequence.

also made minor changes
- rename python api functions _rip to _separate
- fixed bmesh iterator being iterable its self (some parts of python expect this)
- fix memory leak in bmesh python api.
This commit is contained in:
2012-03-09 00:01:38 +00:00
parent 06b2343b50
commit 27d43f3fd3
6 changed files with 154 additions and 56 deletions

View File

@@ -41,7 +41,7 @@
* TESTING ONLY! */ * TESTING ONLY! */
// #define USE_DEBUG_INDEX_MEMCHECK // #define USE_DEBUG_INDEX_MEMCHECK
int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *etarget); static int bm_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep);
#ifdef USE_DEBUG_INDEX_MEMCHECK #ifdef USE_DEBUG_INDEX_MEMCHECK
#define DEBUG_MEMCHECK_INDEX_INVALIDATE(ele) \ #define DEBUG_MEMCHECK_INDEX_INVALIDATE(ele) \
@@ -1739,14 +1739,16 @@ static int bm_vert_splice(BMesh *bm, BMVert *v, BMVert *vtarget)
} }
/** /**
* \brief Cut Vert * \brief Separate Vert
* *
* Cut all disjoint fans that meet at a vertex, making a unique * Separates all disjoint fans that meet at a vertex, making a unique
* vertex for each region. returns an array of all resulting vertices. * vertex for each region. returns an array of all resulting vertices.
* *
* \note this is a low level function, bm_edge_separate needs to run on edges first
*
* \return Success * \return Success
*/ */
static int bm_vert_cut(BMesh *bm, BMVert *v, BMVert ***vout, int *len) int bm_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len)
{ {
BMEdge **stack = NULL; BMEdge **stack = NULL;
BLI_array_declare(stack); BLI_array_declare(stack);
@@ -1758,7 +1760,7 @@ static int bm_vert_cut(BMesh *bm, BMVert *v, BMVert ***vout, int *len)
int i, maxindex; int i, maxindex;
BMLoop *nl; BMLoop *nl;
visithash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "bmesh_vert_cut visithash"); visithash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
maxindex = 0; maxindex = 0;
BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) { BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, v) {
@@ -1786,7 +1788,7 @@ static int bm_vert_cut(BMesh *bm, BMVert *v, BMVert ***vout, int *len)
} }
/* Make enough verts to split v for each group */ /* Make enough verts to split v for each group */
verts = MEM_callocN(sizeof(BMVert *) * maxindex, "bmesh_vert_cut"); verts = MEM_callocN(sizeof(BMVert *) * maxindex, __func__);
verts[0] = v; verts[0] = v;
for (i = 1; i < maxindex; i++) { for (i = 1; i < maxindex; i++) {
verts[i] = BM_vert_create(bm, v->co, v); verts[i] = BM_vert_create(bm, v->co, v);
@@ -1829,12 +1831,12 @@ static int bm_vert_cut(BMesh *bm, BMVert *v, BMVert ***vout, int *len)
BM_CHECK_ELEMENT(bm, verts[i]); BM_CHECK_ELEMENT(bm, verts[i]);
} }
if (len != NULL) { if (r_vout_len != NULL) {
*len = maxindex; *r_vout_len = maxindex;
} }
if (vout != NULL) { if (r_vout != NULL) {
*vout = verts; *r_vout = verts;
} }
else { else {
MEM_freeN(verts); MEM_freeN(verts);
@@ -1843,6 +1845,24 @@ static int bm_vert_cut(BMesh *bm, BMVert *v, BMVert ***vout, int *len)
return TRUE; return TRUE;
} }
/**
* High level function which wraps both #bm_vert_separate and #bm_edge_separate
*/
int BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
BMEdge **e_in, int e_in_len)
{
int i;
for (i = 0; i < e_in_len; i++) {
BMEdge *e = e_in[i];
if (e->l && BM_vert_in_edge(e, v)) {
bm_edge_separate(bm, e, e->l);
}
}
return bm_vert_separate(bm, v, r_vout, r_vout_len);
}
/** /**
* \brief Splice Edge * \brief Splice Edge
* *
@@ -1881,22 +1901,22 @@ int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *etarget)
} }
/** /**
* \brief Cut Edge * \brief Separate Edge
* *
* Cuts a single edge into two edge: the original edge and * Separates a single edge into two edge: the original edge and
* a new edge that has only \a cutl in its radial. * a new edge that has only \a l_sep in its radial.
* *
* \return Success * \return Success
* *
* \note Does nothing if \a cutl is already the only loop in the * \note Does nothing if \a l_sep is already the only loop in the
* edge radial. * edge radial.
*/ */
static int bm_edge_cut(BMesh *bm, BMEdge *e, BMLoop *cutl) static int bm_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep)
{ {
BMEdge *ne; BMEdge *ne;
int radlen; int radlen;
BLI_assert(cutl->e == e); BLI_assert(l_sep->e == e);
BLI_assert(e->l); BLI_assert(e->l);
radlen = bmesh_radial_length(e->l); radlen = bmesh_radial_length(e->l);
@@ -1905,14 +1925,14 @@ static int bm_edge_cut(BMesh *bm, BMEdge *e, BMLoop *cutl)
return TRUE; return TRUE;
} }
if (cutl == e->l) { if (l_sep == e->l) {
e->l = cutl->radial_next; e->l = l_sep->radial_next;
} }
ne = BM_edge_create(bm, e->v1, e->v2, e, FALSE); ne = BM_edge_create(bm, e->v1, e->v2, e, FALSE);
bmesh_radial_loop_remove(cutl, e); bmesh_radial_loop_remove(l_sep, e);
bmesh_radial_append(ne, cutl); bmesh_radial_append(ne, l_sep);
cutl->e = ne; l_sep->e = ne;
BLI_assert(bmesh_radial_length(e->l) == radlen - 1); BLI_assert(bmesh_radial_length(e->l) == radlen - 1);
BLI_assert(bmesh_radial_length(ne->l) == 1); BLI_assert(bmesh_radial_length(ne->l) == 1);
@@ -1939,8 +1959,8 @@ BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *sl)
/* peel the face from the edge radials on both sides of the /* peel the face from the edge radials on both sides of the
* loop vert, disconnecting the face from its fan */ * loop vert, disconnecting the face from its fan */
bm_edge_cut(bm, sl->e, sl); bm_edge_separate(bm, sl->e, sl);
bm_edge_cut(bm, sl->prev->e, sl->prev); bm_edge_separate(bm, sl->prev->e, sl->prev);
if (bmesh_disk_count(sv) == 2) { if (bmesh_disk_count(sv) == 2) {
/* If there are still only two edges out of sv, then /* If there are still only two edges out of sv, then
@@ -1949,7 +1969,7 @@ BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *sl)
} }
/* Update the disk start, so that v->e points to an edge /* Update the disk start, so that v->e points to an edge
* not touching the split loop. This is so that bmesh_vert_cut * not touching the split loop. This is so that BM_vert_split
* will leave the original sv on some *other* fan (not the * will leave the original sv on some *other* fan (not the
* one-face fan that holds the unglue face). */ * one-face fan that holds the unglue face). */
while (sv->e == sl->e || sv->e == sl->prev->e) { while (sv->e == sl->e || sv->e == sl->prev->e) {
@@ -1958,7 +1978,7 @@ BMVert *bmesh_urmv_loop(BMesh *bm, BMLoop *sl)
/* Split all fans connected to the vert, duplicating it for /* Split all fans connected to the vert, duplicating it for
* each fans. */ * each fans. */
bm_vert_cut(bm, sv, &vtar, &len); bm_vert_separate(bm, sv, &vtar, &len);
/* There should have been at least two fans cut apart here, /* There should have been at least two fans cut apart here,
* otherwise the early exit would have kicked in. */ * otherwise the early exit would have kicked in. */

View File

@@ -33,18 +33,20 @@ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example);
BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, int nodouble); BMEdge *BM_edge_create(BMesh *bm, BMVert *v1, BMVert *v2, const BMEdge *example, int nodouble);
BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, int nodouble); BMFace *BM_face_create(BMesh *bm, BMVert **verts, BMEdge **edges, const int len, int nodouble);
void BM_face_edges_kill(BMesh *bm, BMFace *f); void BM_face_edges_kill(BMesh *bm, BMFace *f);
void BM_face_verts_kill(BMesh *bm, BMFace *f); void BM_face_verts_kill(BMesh *bm, BMFace *f);
void BM_face_kill(BMesh *bm, BMFace *f); void BM_face_kill(BMesh *bm, BMFace *f);
void BM_edge_kill(BMesh *bm, BMEdge *e); void BM_edge_kill(BMesh *bm, BMEdge *e);
void BM_vert_kill(BMesh *bm, BMVert *v); void BM_vert_kill(BMesh *bm, BMVert *v);
int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *etarget); int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *etarget);
int bmesh_loop_reverse(BMesh *bm, BMFace *f); int bmesh_loop_reverse(BMesh *bm, BMFace *f);
BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface); BMFace *BM_faces_join(BMesh *bm, BMFace **faces, int totface);
int BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len,
BMEdge **e_in, int e_in_len);
/* EULER API - For modifying structure */ /* EULER API - For modifying structure */
BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1,

View File

@@ -2309,6 +2309,7 @@ void BPy_BM_init_types(void)
/* only 1 iteratir so far */ /* only 1 iteratir so far */
BPy_BMIter_Type.tp_iternext = (iternextfunc)bpy_bmiter_next; BPy_BMIter_Type.tp_iternext = (iternextfunc)bpy_bmiter_next;
BPy_BMIter_Type.tp_iter = PyObject_SelfIter;
BPy_BMesh_Type.tp_dealloc = (destructor)bpy_bmesh_dealloc; BPy_BMesh_Type.tp_dealloc = (destructor)bpy_bmesh_dealloc;
BPy_BMVert_Type.tp_dealloc = (destructor)bpy_bmvert_dealloc; BPy_BMVert_Type.tp_dealloc = (destructor)bpy_bmvert_dealloc;
@@ -2673,3 +2674,15 @@ err_cleanup:
return NULL; return NULL;
} }
} }
PyObject *BPy_BMElem_Array_As_Tuple(BMesh *bm, BMHeader **elem, Py_ssize_t elem_len)
{
Py_ssize_t i;
PyObject *ret = PyTuple_New(elem_len);
for (i = 0; i < elem_len; i++) {
PyTuple_SET_ITEM(ret, i, BPy_BMElem_CreatePyObject(bm, elem[i]));
}
return ret;
}

View File

@@ -137,6 +137,9 @@ void *BPy_BMElem_PySeq_As_Array(BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_
const char do_unique_check, const char do_bm_check, const char do_unique_check, const char do_bm_check,
const char *error_prefix); const char *error_prefix);
PyObject *BPy_BMElem_Array_As_Tuple(BMesh *bm, BMHeader **elem, Py_ssize_t elem_len);
#define BPY_BM_CHECK_OBJ(obj) if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return NULL; } (void)0 #define BPY_BM_CHECK_OBJ(obj) if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return NULL; } (void)0
#define BPY_BM_CHECK_INT(obj) if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return -1; } (void)0 #define BPY_BM_CHECK_INT(obj) if (UNLIKELY(bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1)) { return -1; } (void)0

View File

@@ -38,6 +38,8 @@
#include "BLI_utildefines.h" #include "BLI_utildefines.h"
#include "MEM_guardedalloc.h"
#include "bmesh_py_utils.h" /* own include */ #include "bmesh_py_utils.h" /* own include */
@@ -196,6 +198,67 @@ static PyObject *bpy_bm_utils_vert_dissolve(PyObject *UNUSED(self), PyObject *ar
return PyBool_FromLong((BM_vert_dissolve(bm, py_vert->v))); return PyBool_FromLong((BM_vert_dissolve(bm, py_vert->v)));
} }
PyDoc_STRVAR(bpy_bm_utils_vert_separate_doc,
".. method:: vert_separate(vert, edges)\n"
"\n"
" Separate this vertex at every edge.\n"
"\n"
" :arg vert: The vert to be separated.\n"
" :type vert: :class:`BMVert`\n"
" :arg edges: The edges to separated.\n"
" :type edges: :class:`BMEdge`\n"
" :return: The newly separated verts (including the vertex passed).\n"
" :rtype: tuple of :class:`BMVert`\n"
);
static PyObject *bpy_bm_utils_vert_separate(PyObject *UNUSED(self), PyObject *args)
{
BPy_BMVert *py_vert;
PyObject *edge_seq;
BMesh *bm;
BMVert **elem;
int elem_len;
/* edges to split */
BMEdge **edge_array;
Py_ssize_t edge_array_len;
PyObject *ret;
if (!PyArg_ParseTuple(args, "O!O:vert_separate",
&BPy_BMVert_Type, &py_vert,
&edge_seq))
{
return NULL;
}
BPY_BM_CHECK_OBJ(py_vert);
bm = py_vert->bm;
edge_array = BPy_BMElem_PySeq_As_Array(&bm, edge_seq, 0, PY_SSIZE_T_MAX,
&edge_array_len, &BPy_BMEdge_Type,
TRUE, TRUE, "vert_separate(...)");
if (edge_array == NULL) {
return NULL;
}
if (BM_vert_separate(bm, py_vert->v, &elem, &elem_len, edge_array, edge_array_len)) {
/* return collected verts */
ret = BPy_BMElem_Array_As_Tuple(bm, (BMHeader **)elem, elem_len);
MEM_freeN(elem);
}
else {
ret = PyTuple_New(0);
}
PyMem_FREE(edge_array);
return ret;
}
PyDoc_STRVAR(bpy_bm_utils_edge_split_doc, PyDoc_STRVAR(bpy_bm_utils_edge_split_doc,
".. method:: edge_split(edge, vert, fac)\n" ".. method:: edge_split(edge, vert, fac)\n"
@@ -408,6 +471,8 @@ static PyObject *bpy_bm_utils_face_join(PyObject *UNUSED(self), PyObject *value)
* --------------------------- */ * --------------------------- */
f_new = BM_faces_join(bm, face_array, (int)face_seq_len); f_new = BM_faces_join(bm, face_array, (int)face_seq_len);
PyMem_FREE(face_array);
if (f_new) { if (f_new) {
return BPy_BMFace_CreatePyObject(bm, f_new); return BPy_BMFace_CreatePyObject(bm, f_new);
} }
@@ -417,23 +482,23 @@ static PyObject *bpy_bm_utils_face_join(PyObject *UNUSED(self), PyObject *value)
} }
PyDoc_STRVAR(bpy_bm_utils_face_vert_rip_doc, PyDoc_STRVAR(bpy_bm_utils_face_vert_separate_doc,
".. method:: face_vert_rip(face, vert)\n" ".. method:: face_vert_separate(face, vert)\n"
"\n" "\n"
" Rip a vertex in a face away and add a new vertex.\n" " Rip a vertex in a face away and add a new vertex.\n"
"\n" "\n"
" :arg face: The face to rip.\n" " :arg face: The face to separate.\n"
" :type face: :class:`BMFace`\n" " :type face: :class:`BMFace`\n"
" :arg vert: A vertex in the face to rip.\n" " :arg vert: A vertex in the face to separate.\n"
" :type vert: :class:`BMVert`\n" " :type vert: :class:`BMVert`\n"
" :return vert: The newly created vertex or None of failure.\n" " :return vert: The newly created vertex or None of failure.\n"
" :rtype vert: :class:`BMVert`\n" " :rtype vert: :class:`BMVert`\n"
"\n" "\n"
" .. note::\n" " .. note::\n"
"\n" "\n"
" This is the same as loop_rip, and has only been added for convenience.\n" " This is the same as loop_separate, and has only been added for convenience.\n"
); );
static PyObject *bpy_bm_utils_face_vert_rip(PyObject *UNUSED(self), PyObject *args) static PyObject *bpy_bm_utils_face_vert_separate(PyObject *UNUSED(self), PyObject *args)
{ {
BPy_BMFace *py_face; BPy_BMFace *py_face;
BPy_BMVert *py_vert; BPy_BMVert *py_vert;
@@ -442,7 +507,7 @@ static PyObject *bpy_bm_utils_face_vert_rip(PyObject *UNUSED(self), PyObject *ar
BMLoop *l; BMLoop *l;
BMVert *v_new; BMVert *v_new;
if (!PyArg_ParseTuple(args, "O!O!:face_vert_rip", if (!PyArg_ParseTuple(args, "O!O!:face_vert_separate",
&BPy_BMFace_Type, &py_face, &BPy_BMFace_Type, &py_face,
&BPy_BMVert_Type, &py_vert)) &BPy_BMVert_Type, &py_vert))
{ {
@@ -468,7 +533,7 @@ static PyObject *bpy_bm_utils_face_vert_rip(PyObject *UNUSED(self), PyObject *ar
return NULL; return NULL;
} }
v_new = BM_face_loop_rip(bm, l); v_new = BM_face_loop_separate(bm, l);
if (v_new != l->v) { if (v_new != l->v) {
return BPy_BMVert_CreatePyObject(bm, v_new); return BPy_BMVert_CreatePyObject(bm, v_new);
@@ -505,24 +570,24 @@ static PyObject *bpy_bm_utils_face_flip(PyObject *UNUSED(self), BPy_BMFace *valu
PyDoc_STRVAR(bpy_bm_utils_loop_rip_doc, PyDoc_STRVAR(bpy_bm_utils_loop_separate_doc,
".. method:: loop_rip(loop)\n" ".. method:: loop_separate(loop)\n"
"\n" "\n"
" Rip a vertex in a face away and add a new vertex.\n" " Rip a vertex in a face away and add a new vertex.\n"
"\n" "\n"
" :arg loop: The to rip.\n" " :arg loop: The to separate.\n"
" :type loop: :class:`BMFace`\n" " :type loop: :class:`BMFace`\n"
" :return vert: The newly created vertex or None of failure.\n" " :return vert: The newly created vertex or None of failure.\n"
" :rtype vert: :class:`BMVert`\n" " :rtype vert: :class:`BMVert`\n"
); );
static PyObject *bpy_bm_utils_loop_rip(PyObject *UNUSED(self), BPy_BMLoop *value) static PyObject *bpy_bm_utils_loop_separate(PyObject *UNUSED(self), BPy_BMLoop *value)
{ {
BMesh *bm; BMesh *bm;
BMVert *v_new; BMVert *v_new;
if (!BPy_BMLoop_Check(value)) { if (!BPy_BMLoop_Check(value)) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"loop_rip(loop): BMLoop expected, not '%.200s'", "loop_separate(loop): BMLoop expected, not '%.200s'",
Py_TYPE(value)->tp_name); Py_TYPE(value)->tp_name);
return NULL; return NULL;
} }
@@ -531,7 +596,7 @@ static PyObject *bpy_bm_utils_loop_rip(PyObject *UNUSED(self), BPy_BMLoop *value
bm = value->bm; bm = value->bm;
v_new = BM_face_loop_rip(bm, value->l); v_new = BM_face_loop_separate(bm, value->l);
if (v_new != value->l->v) { if (v_new != value->l->v) {
return BPy_BMVert_CreatePyObject(bm, v_new); return BPy_BMVert_CreatePyObject(bm, v_new);
@@ -545,14 +610,15 @@ static PyObject *bpy_bm_utils_loop_rip(PyObject *UNUSED(self), BPy_BMLoop *value
static struct PyMethodDef BPy_BM_utils_methods[] = { static struct PyMethodDef BPy_BM_utils_methods[] = {
{"vert_collapse_edge", (PyCFunction)bpy_bm_utils_vert_collapse_edge, METH_VARARGS, bpy_bm_utils_vert_collapse_edge_doc}, {"vert_collapse_edge", (PyCFunction)bpy_bm_utils_vert_collapse_edge, METH_VARARGS, bpy_bm_utils_vert_collapse_edge_doc},
{"vert_collapse_faces", (PyCFunction)bpy_bm_utils_vert_collapse_faces, METH_VARARGS, bpy_bm_utils_vert_collapse_faces_doc}, {"vert_collapse_faces", (PyCFunction)bpy_bm_utils_vert_collapse_faces, METH_VARARGS, bpy_bm_utils_vert_collapse_faces_doc},
{"vert_dissolve", (PyCFunction)bpy_bm_utils_vert_dissolve, METH_VARARGS, bpy_bm_utils_vert_dissolve_doc}, {"vert_dissolve", (PyCFunction)bpy_bm_utils_vert_dissolve, METH_VARARGS, bpy_bm_utils_vert_dissolve_doc}, /* could use METH_O */
{"vert_separate", (PyCFunction)bpy_bm_utils_vert_separate, METH_VARARGS, bpy_bm_utils_vert_separate_doc},
{"edge_split", (PyCFunction)bpy_bm_utils_edge_split, METH_VARARGS, bpy_bm_utils_edge_split_doc}, {"edge_split", (PyCFunction)bpy_bm_utils_edge_split, METH_VARARGS, bpy_bm_utils_edge_split_doc},
{"edge_rotate", (PyCFunction)bpy_bm_utils_edge_rotate, METH_VARARGS, bpy_bm_utils_edge_rotate_doc}, {"edge_rotate", (PyCFunction)bpy_bm_utils_edge_rotate, METH_VARARGS, bpy_bm_utils_edge_rotate_doc},
{"face_split", (PyCFunction)bpy_bm_utils_face_split, METH_VARARGS, bpy_bm_utils_face_split_doc}, {"face_split", (PyCFunction)bpy_bm_utils_face_split, METH_VARARGS, bpy_bm_utils_face_split_doc},
{"face_join", (PyCFunction)bpy_bm_utils_face_join, METH_O, bpy_bm_utils_face_join_doc}, {"face_join", (PyCFunction)bpy_bm_utils_face_join, METH_O, bpy_bm_utils_face_join_doc},
{"face_vert_rip", (PyCFunction)bpy_bm_utils_face_vert_rip, METH_VARARGS, bpy_bm_utils_face_vert_rip_doc}, {"face_vert_separate", (PyCFunction)bpy_bm_utils_face_vert_separate, METH_VARARGS, bpy_bm_utils_face_vert_separate_doc},
{"face_flip", (PyCFunction)bpy_bm_utils_face_flip, METH_O, bpy_bm_utils_face_flip_doc}, {"face_flip", (PyCFunction)bpy_bm_utils_face_flip, METH_O, bpy_bm_utils_face_flip_doc},
{"loop_rip", (PyCFunction)bpy_bm_utils_loop_rip, METH_O, bpy_bm_utils_loop_rip_doc}, {"loop_separate", (PyCFunction)bpy_bm_utils_loop_separate, METH_O, bpy_bm_utils_loop_separate_doc},
{NULL, NULL, 0, NULL} {NULL, NULL, 0, NULL}
}; };

View File

@@ -1324,12 +1324,6 @@ PyTypeObject BPy_IDArray_Type = {
/*********** ID Property Group iterator ********/ /*********** ID Property Group iterator ********/
static PyObject *IDGroup_Iter_iterself(PyObject *self)
{
Py_XINCREF(self);
return self;
}
static PyObject *IDGroup_Iter_repr(BPy_IDGroup_Iter *self) static PyObject *IDGroup_Iter_repr(BPy_IDGroup_Iter *self)
{ {
return PyUnicode_FromFormat("(ID Property Group Iter \"%s\")", self->group->prop->name); return PyUnicode_FromFormat("(ID Property Group Iter \"%s\")", self->group->prop->name);
@@ -1412,7 +1406,7 @@ PyTypeObject BPy_IDGroup_Iter_Type = {
/*** Added in release 2.2 ***/ /*** Added in release 2.2 ***/
/* Iterators */ /* Iterators */
IDGroup_Iter_iterself, /* getiterfunc tp_iter; */ PyObject_SelfIter, /* getiterfunc tp_iter; */
(iternextfunc) BPy_Group_Iter_Next, /* iternextfunc tp_iternext; */ (iternextfunc) BPy_Group_Iter_Next, /* iternextfunc tp_iternext; */
}; };