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:
@@ -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);
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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,19 +87,25 @@ 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);
|
}
|
||||||
if (ese) {
|
else {
|
||||||
return BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head);
|
ese = BLI_findlink(&self->bm->selected, keynum);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PyErr_Format(PyExc_IndexError,
|
if (ese) {
|
||||||
"BMElemSeq[index]: index %d out of range", keynum);
|
return BPy_BMElem_CreatePyObject(self->bm, &ese->ele->head);
|
||||||
return NULL;
|
}
|
||||||
|
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)
|
static PyObject *bpy_bmeditselseq_subscript_slice(BPy_BMEditSelSeq *self, Py_ssize_t start, Py_ssize_t stop)
|
||||||
|
@@ -1564,7 +1564,7 @@ static PyObject *bpy_bmedgeseq_get(BPy_BMElemSeq *self, PyObject *args)
|
|||||||
return NULL;
|
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);
|
ret = BPy_BMEdge_CreatePyObject(bm, e);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -2572,7 +2572,7 @@ void *BPy_BMElem_PySeq_As_Array(BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_
|
|||||||
PyObject *seq_fast;
|
PyObject *seq_fast;
|
||||||
*r_size = 0;
|
*r_size = 0;
|
||||||
|
|
||||||
if (!(seq_fast=PySequence_Fast(seq, error_prefix))) {
|
if (!(seq_fast = PySequence_Fast(seq, error_prefix))) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@@ -50,11 +50,11 @@ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length,
|
|||||||
Py_ssize_t value_len;
|
Py_ssize_t value_len;
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
|
|
||||||
if (!(value_fast=PySequence_Fast(value, error_prefix))) {
|
if (!(value_fast = PySequence_Fast(value, error_prefix))) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_len= PySequence_Fast_GET_SIZE(value_fast);
|
value_len = PySequence_Fast_GET_SIZE(value_fast);
|
||||||
|
|
||||||
if (value_len != length) {
|
if (value_len != length) {
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
@@ -69,13 +69,13 @@ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length,
|
|||||||
if (is_double) {
|
if (is_double) {
|
||||||
double *array_double= array;
|
double *array_double= array;
|
||||||
for (i=0; i<length; i++) {
|
for (i=0; i<length; i++) {
|
||||||
array_double[i]= PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i));
|
array_double[i] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
float *array_float= array;
|
float *array_float= array;
|
||||||
for (i=0; i<length; i++) {
|
for (i=0; i<length; i++) {
|
||||||
array_float[i]= PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i));
|
array_float[i] = PyFloat_AsDouble(PySequence_Fast_GET_ITEM(value_fast, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,13 +83,13 @@ int PyC_AsArray(void *array, PyObject *value, const Py_ssize_t length,
|
|||||||
/* could use is_double for 'long int' but no use now */
|
/* could use is_double for 'long int' but no use now */
|
||||||
int *array_int= array;
|
int *array_int= array;
|
||||||
for (i=0; i<length; i++) {
|
for (i=0; i<length; i++) {
|
||||||
array_int[i]= PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i));
|
array_int[i] = PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == &PyBool_Type) {
|
else if (type == &PyBool_Type) {
|
||||||
int *array_bool= array;
|
int *array_bool= array;
|
||||||
for (i=0; i<length; i++) {
|
for (i=0; i<length; i++) {
|
||||||
array_bool[i]= (PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i)) != 0);
|
array_bool[i] = (PyLong_AsSsize_t(PySequence_Fast_GET_ITEM(value_fast, i)) != 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Reference in New Issue
Block a user