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.
This commit is contained in:
2012-03-03 22:07:58 +00:00
parent 685fda4f13
commit 1531e3677a
5 changed files with 60 additions and 22 deletions

View File

@@ -41,15 +41,16 @@ extern "C" {
#endif #endif
void BLI_insertlink(struct ListBase *listbase, void *vprevlink, void *vnewlink); 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_findindex(const struct ListBase *listbase, void *vlink);
int BLI_findstringindex(const struct ListBase *listbase, const char *id, const int offset); int BLI_findstringindex(const struct ListBase *listbase, const char *id, const int offset);
/* find forwards */ /* 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(const struct ListBase *listbase, const char *id, const int offset);
void *BLI_findstring_ptr(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 */ /* 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(const struct ListBase *listbase, const char *id, const int offset);
void *BLI_rfindstring_ptr(const struct ListBase *listbase, const char *id, const int offset); void *BLI_rfindstring_ptr(const struct ListBase *listbase, const char *id, const int offset);

View File

@@ -338,6 +338,21 @@ void *BLI_findlink(const ListBase *listbase, int number)
return link; 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) int BLI_findindex(const ListBase *listbase, void *vlink)
{ {
Link *link= NULL; Link *link= NULL;

View File

@@ -23,10 +23,11 @@
* ***** END GPL LICENSE BLOCK ***** * ***** END GPL LICENSE BLOCK *****
*/ */
/** \file blender/python/bmesh/bmesh_py_api.c /** \file blender/python/bmesh/bmesh_py_select.c
* \ingroup pybmesh * \ingroup pybmesh
* *
* This file defines the 'bmesh' module. * This file defines the types for 'BMesh.select_history'
* sequence and iterator.
*/ */
#include <Python.h> #include <Python.h>
@@ -47,9 +48,24 @@
#include "bmesh_py_api.h" /* own include */ #include "bmesh_py_api.h" /* own include */
static PyGetSetDef bpy_bmeditselseq_getseters[] = { PyDoc_STRVAR(bpy_bmeditselseq_active_doc,
// {(char *)"verts", (getter)bpy_bmeditselseq_get, (setter)NULL, (char *)bpy_bmesh_verts_doc, (void *)BM_VERTS_OF_MESH}, "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 */ {NULL, NULL, NULL, NULL, NULL} /* Sentinel */
}; };
@@ -71,20 +87,26 @@ static Py_ssize_t bpy_bmeditselseq_length(BPy_BMEditSelSeq *self)
static PyObject *bpy_bmeditselseq_subscript_int(BPy_BMEditSelSeq *self, int keynum) static PyObject *bpy_bmeditselseq_subscript_int(BPy_BMEditSelSeq *self, int keynum)
{ {
BMEditSelection *ese;
BPY_BM_CHECK_OBJ(self); 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) {
if (keynum >= 0) { ese = BLI_rfindlink(&self->bm->selected, -1 - keynum);
BMEditSelection *ese = BLI_findlink(&self->bm->selected, keynum); }
else {
ese = BLI_findlink(&self->bm->selected, keynum);
}
if (ese) { if (ese) {
return BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head); return BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head);
} }
} else {
PyErr_Format(PyExc_IndexError, PyErr_Format(PyExc_IndexError,
"BMElemSeq[index]: index %d out of range", keynum); "BMElemSeq[index]: index %d out of range", keynum);
return NULL; return NULL;
} }
}
static PyObject *bpy_bmeditselseq_subscript_slice(BPy_BMEditSelSeq *self, Py_ssize_t start, Py_ssize_t stop) static PyObject *bpy_bmeditselseq_subscript_slice(BPy_BMEditSelSeq *self, Py_ssize_t start, Py_ssize_t stop)
{ {