Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2014-10-28 11:49:02 +0300
committerCampbell Barton <ideasman42@gmail.com>2014-10-28 12:03:54 +0300
commit785b90d7efd048a3c6d586db3760ef31fb41b1ca (patch)
tree9f948b78994b05fe244e408a03f41afcf27aec12 /source/blender
parent6c2ce7a3828e92083dfdad85eb683f4d27ed852b (diff)
BMesh Py API: Fast index lookups for vert/edge/faces
This changes the Py API to use array lookup table. Previously this could be very slow since it would loop over all elements. Now the python script is responsible for creating the internal lookup table (as with C code). This will break some scripts.
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/python/bmesh/bmesh_py_types.c59
1 files changed, 56 insertions, 3 deletions
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c
index a31345cd7f5..8c13a66bea0 100644
--- a/source/blender/python/bmesh/bmesh_py_types.c
+++ b/source/blender/python/bmesh/bmesh_py_types.c
@@ -2311,6 +2311,22 @@ static PyObject *bpy_bmelemseq_index_update(BPy_BMElemSeq *self)
Py_RETURN_NONE;
}
+PyDoc_STRVAR(bpy_bmelemseq_ensure_lookup_table_doc,
+".. method:: ensure_lookup_table()\n"
+"\n"
+" Ensure internal data needed for int subscription is initialized with verts/edges/faces, eg ``bm.verts[index]``.\n"
+"\n"
+" This needs to be called again after adding/removing data in this sequence."
+);
+static PyObject *bpy_bmelemseq_ensure_lookup_table(BPy_BMElemSeq *self)
+{
+ BPY_BM_CHECK_OBJ(self);
+
+ BM_mesh_elem_table_ensure(self->bm, bm_iter_itype_htype_map[self->itype]);
+
+ Py_RETURN_NONE;
+}
+
PyDoc_STRVAR(bpy_bmelemseq_sort_doc,
".. method:: sort(key=None, reverse=False)\n"
"\n"
@@ -2605,6 +2621,7 @@ static struct PyMethodDef bpy_bmvertseq_methods[] = {
/* odd function, initializes index values */
{"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc},
+ {"ensure_lookup_table", (PyCFunction)bpy_bmelemseq_ensure_lookup_table, METH_NOARGS, bpy_bmelemseq_ensure_lookup_table_doc},
{"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, bpy_bmelemseq_sort_doc},
{NULL, NULL, 0, NULL}
};
@@ -2617,6 +2634,7 @@ static struct PyMethodDef bpy_bmedgeseq_methods[] = {
/* odd function, initializes index values */
{"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc},
+ {"ensure_lookup_table", (PyCFunction)bpy_bmelemseq_ensure_lookup_table, METH_NOARGS, bpy_bmelemseq_ensure_lookup_table_doc},
{"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, bpy_bmelemseq_sort_doc},
{NULL, NULL, 0, NULL}
};
@@ -2629,6 +2647,7 @@ static struct PyMethodDef bpy_bmfaceseq_methods[] = {
/* odd function, initializes index values */
{"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc},
+ {"ensure_lookup_table", (PyCFunction)bpy_bmelemseq_ensure_lookup_table, METH_NOARGS, bpy_bmelemseq_ensure_lookup_table_doc},
{"sort", (PyCFunction)bpy_bmelemseq_sort, METH_VARARGS | METH_KEYWORDS, bpy_bmelemseq_sort_doc},
{NULL, NULL, 0, NULL}
};
@@ -2725,9 +2744,43 @@ static PyObject *bpy_bmelemseq_subscript_int(BPy_BMElemSeq *self, int keynum)
if (keynum < 0) keynum += bpy_bmelemseq_length(self); /* only get length on negative value, may loop entire seq */
if (keynum >= 0) {
- BMHeader *ele = BM_iter_at_index(self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL, keynum);
- if (ele) {
- return BPy_BMElem_CreatePyObject(self->bm, ele);
+ if (self->itype <= BM_FACES_OF_MESH) {
+ if ((self->bm->elem_table_dirty & bm_iter_itype_htype_map[self->itype]) == 0) {
+ BMHeader *ele = NULL;
+ switch (self->itype) {
+ case BM_VERTS_OF_MESH:
+ if (keynum < self->bm->totvert) {
+ ele = (BMHeader *)self->bm->vtable[keynum];
+ }
+ break;
+ case BM_EDGES_OF_MESH:
+ if (keynum < self->bm->totedge) {
+ ele = (BMHeader *)self->bm->etable[keynum];
+ }
+ break;
+ case BM_FACES_OF_MESH:
+ if (keynum < self->bm->totface) {
+ ele = (BMHeader *)self->bm->ftable[keynum];
+ }
+ break;
+ }
+ if (ele) {
+ return BPy_BMElem_CreatePyObject(self->bm, ele);
+ }
+ /* fall through to index error below */
+ }
+ else {
+ PyErr_SetString(PyExc_IndexError,
+ "BMElemSeq[index]: outdated internal index table, "
+ "run ensure_lookup_table() first");
+ return NULL;
+ }
+ }
+ else {
+ BMHeader *ele = BM_iter_at_index(self->bm, self->itype, self->py_ele ? self->py_ele->ele : NULL, keynum);
+ if (ele) {
+ return BPy_BMElem_CreatePyObject(self->bm, ele);
+ }
}
}