From 1531e3677a639b9265d26d73e3bc5ee21e996af8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 3 Mar 2012 22:07:58 +0000 Subject: [PATCH] bmesh py api * add BLI_rfindlink for reverse index lookup (used so bm.select_history[-1] doesn't have to loop the entire list twice). * add bm.select_history.active so you can get the last selected item or None without having to check seq length. --- source/blender/blenlib/BLI_listbase.h | 3 +- source/blender/blenlib/intern/listbase.c | 15 ++++++ source/blender/python/bmesh/bmesh_py_select.c | 48 ++++++++++++++----- source/blender/python/bmesh/bmesh_py_types.c | 4 +- source/blender/python/generic/py_capi_utils.c | 12 ++--- 5 files changed, 60 insertions(+), 22 deletions(-) diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index b0a5e80d850..abe7eacb1ac 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -41,15 +41,16 @@ extern "C" { #endif void BLI_insertlink(struct ListBase *listbase, void *vprevlink, void *vnewlink); -void *BLI_findlink(const struct ListBase *listbase, int number); int BLI_findindex(const struct ListBase *listbase, void *vlink); int BLI_findstringindex(const struct ListBase *listbase, const char *id, const int offset); /* find forwards */ +void *BLI_findlink(const struct ListBase *listbase, int number); void *BLI_findstring(const struct ListBase *listbase, const char *id, const int offset); void *BLI_findstring_ptr(const struct ListBase *listbase, const char *id, const int offset); /* find backwards */ +void *BLI_rfindlink(const struct ListBase *listbase, int number); void *BLI_rfindstring(const struct ListBase *listbase, const char *id, const int offset); void *BLI_rfindstring_ptr(const struct ListBase *listbase, const char *id, const int offset); diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index 52fd857d6e4..6155bf83a57 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -338,6 +338,21 @@ void *BLI_findlink(const ListBase *listbase, int number) return link; } +void *BLI_rfindlink(const ListBase *listbase, int number) +{ + Link *link = NULL; + + if (number >= 0) { + link = listbase->last; + while (link != NULL && number != 0) { + number--; + link = link->prev; + } + } + + return link; +} + int BLI_findindex(const ListBase *listbase, void *vlink) { Link *link= NULL; diff --git a/source/blender/python/bmesh/bmesh_py_select.c b/source/blender/python/bmesh/bmesh_py_select.c index 5630b4ac712..fd9f329f7c0 100644 --- a/source/blender/python/bmesh/bmesh_py_select.c +++ b/source/blender/python/bmesh/bmesh_py_select.c @@ -23,10 +23,11 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/python/bmesh/bmesh_py_api.c +/** \file blender/python/bmesh/bmesh_py_select.c * \ingroup pybmesh * - * This file defines the 'bmesh' module. + * This file defines the types for 'BMesh.select_history' + * sequence and iterator. */ #include @@ -47,9 +48,24 @@ #include "bmesh_py_api.h" /* own include */ -static PyGetSetDef bpy_bmeditselseq_getseters[] = { - // {(char *)"verts", (getter)bpy_bmeditselseq_get, (setter)NULL, (char *)bpy_bmesh_verts_doc, (void *)BM_VERTS_OF_MESH}, +PyDoc_STRVAR(bpy_bmeditselseq_active_doc, +"The last selected element or None (read-only).\n\n:type: :class:`BMVert`, :class:`BMEdge` or :class:`BMFace`" +); +static PyObject *bpy_bmeditselseq_active_get(BPy_BMEditSelSeq *self, void *UNUSED(closure)) +{ + BMEditSelection *ese; + BPY_BM_CHECK_OBJ(self); + if ((ese = self->bm->selected.last)) { + return BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head); + } + else { + Py_RETURN_NONE; + } +} + +static PyGetSetDef bpy_bmeditselseq_getseters[] = { + {(char *)"active", (getter)bpy_bmeditselseq_active_get, (setter)NULL, (char *)bpy_bmeditselseq_active_doc, (void *)BM_VERTS_OF_MESH}, {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; @@ -71,19 +87,25 @@ static Py_ssize_t bpy_bmeditselseq_length(BPy_BMEditSelSeq *self) static PyObject *bpy_bmeditselseq_subscript_int(BPy_BMEditSelSeq *self, int keynum) { + BMEditSelection *ese; + BPY_BM_CHECK_OBJ(self); - if (keynum < 0) keynum += bpy_bmeditselseq_length(self); /* only get length on negative value, may loop entire seq */ - if (keynum >= 0) { - BMEditSelection *ese = BLI_findlink(&self->bm->selected, keynum); - if (ese) { - return BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head); - } + if (keynum < 0) { + ese = BLI_rfindlink(&self->bm->selected, -1 - keynum); + } + else { + ese = BLI_findlink(&self->bm->selected, keynum); } - PyErr_Format(PyExc_IndexError, - "BMElemSeq[index]: index %d out of range", keynum); - return NULL; + if (ese) { + return BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head); + } + else { + PyErr_Format(PyExc_IndexError, + "BMElemSeq[index]: index %d out of range", keynum); + return NULL; + } } static PyObject *bpy_bmeditselseq_subscript_slice(BPy_BMEditSelSeq *self, Py_ssize_t start, Py_ssize_t stop) diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 2d5a60d2190..757f1f2ed90 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -1564,7 +1564,7 @@ static PyObject *bpy_bmedgeseq_get(BPy_BMElemSeq *self, PyObject *args) return NULL; } - if ((e=BM_edge_exists(vert_array[0], vert_array[1]))) { + if ((e = BM_edge_exists(vert_array[0], vert_array[1]))) { ret = BPy_BMEdge_CreatePyObject(bm, e); } else { @@ -2572,7 +2572,7 @@ void *BPy_BMElem_PySeq_As_Array(BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_ PyObject *seq_fast; *r_size = 0; - if (!(seq_fast=PySequence_Fast(seq, error_prefix))) { + if (!(seq_fast = PySequence_Fast(seq, error_prefix))) { return NULL; } else { diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c index 499a691156b..cf352504f71 100644 --- a/source/blender/python/generic/py_capi_utils.c +++ b/source/blender/python/generic/py_capi_utils.c @@ -50,11 +50,11 @@ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length, Py_ssize_t value_len; Py_ssize_t i; - if (!(value_fast=PySequence_Fast(value, error_prefix))) { + if (!(value_fast = PySequence_Fast(value, error_prefix))) { return -1; } - value_len= PySequence_Fast_GET_SIZE(value_fast); + value_len = PySequence_Fast_GET_SIZE(value_fast); if (value_len != length) { Py_DECREF(value); @@ -69,13 +69,13 @@ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length, if (is_double) { double *array_double= array; for (i=0; i