diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-02-22 16:54:53 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-02-22 16:54:53 +0400 |
commit | ccfcc70c8cf08aefabd3a4d8bfeae6156df4bc9b (patch) | |
tree | b786887dd79bcf0b07b8724ebc20d3ed55a72157 | |
parent | 5123238f7d7b3655cd8b4cc3b9da18ee4f4912d3 (diff) |
add slice access to bmesh sequences.
eg:
verts = bm.verts[1:-7]
-rw-r--r-- | source/blender/editors/mesh/bmesh_tools.c | 2 | ||||
-rw-r--r-- | source/blender/python/bmesh/bmesh_py_types.c | 83 |
2 files changed, 83 insertions, 2 deletions
diff --git a/source/blender/editors/mesh/bmesh_tools.c b/source/blender/editors/mesh/bmesh_tools.c index 5c482f72b14..aa5b092322e 100644 --- a/source/blender/editors/mesh/bmesh_tools.c +++ b/source/blender/editors/mesh/bmesh_tools.c @@ -1565,7 +1565,7 @@ static int normals_make_consistent_exec(bContext *C, wmOperator *op) /* doflip has to do with bmesh_rationalize_normals, it's an internal * thing */ - if (!EDBM_CallOpf(em, op, "righthandfaces faces=%hf do_flip=%d", BM_ELEM_SELECT, TRUE)) + if (!EDBM_CallOpf(em, op, "righthandfaces faces=%hf do_flip=%b", BM_ELEM_SELECT, TRUE)) return OPERATOR_CANCELLED; if (RNA_boolean_get(op->ptr, "inside")) diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 7c16d345ce6..f0189d2077b 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -1066,6 +1066,52 @@ static PyObject *bpy_bm_seq_subscript_int(BPy_BMElemSeq *self, int keynum) return NULL; } +static PyObject *bpy_bm_seq_subscript_slice(BPy_BMElemSeq *self, Py_ssize_t start, Py_ssize_t stop) +{ + BMIter iter; + int count = 0; + int ok; + + PyObject *list; + PyObject *item; + BMHeader *ele; + + BPY_BM_CHECK_OBJ(self); + + list = PyList_New(0); + + ok = BM_iter_init(&iter, self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL); + + BLI_assert(ok == TRUE); + + if (UNLIKELY(ok == FALSE)) { + return list; + } + + /* first loop up-until the start */ + for (ok = TRUE; ok; ok = (BM_iter_step(&iter) != NULL)) { + /* PointerRNA itemptr = rna_macro_iter.ptr; */ + if (count == start) { + break; + } + count++; + } + + /* add items until stop */ + while ((ele = BM_iter_step(&iter))) { + item = BPy_BMElem_CreatePyObject(self->bm, ele); + PyList_Append(list, item); + Py_DECREF(item); + + count++; + if (count == stop) { + break; + } + } + + return list; +} + static PyObject *bpy_bm_seq_subscript(BPy_BMElemSeq *self, PyObject *key) { /* dont need error check here */ @@ -1075,7 +1121,42 @@ static PyObject *bpy_bm_seq_subscript(BPy_BMElemSeq *self, PyObject *key) return NULL; return bpy_bm_seq_subscript_int(self, i); } - /* TODO, slice */ + 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, "bpy_prop_collection[slice]: slice steps not supported"); + return NULL; + } + else if (key_slice->start == Py_None && key_slice->stop == Py_None) { + return bpy_bm_seq_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_bm_seq_length(self); + if (start < 0) start += len; + if (stop < 0) start += len; + } + + if (stop - start <= 0) { + return PyList_New(0); + } + else { + return bpy_bm_seq_subscript_slice(self, start, stop); + } + } + } else { PyErr_SetString(PyExc_AttributeError, "BMElemSeq[key]: invalid key, key must be an int"); return NULL; |