diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-02-24 09:56:06 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-02-24 09:56:06 +0400 |
commit | 6b85b96952becb00c6ad1ec185a9ac229a3ea344 (patch) | |
tree | ebad6e50b1fef40754df90a0590153155273b4cf /source/blender | |
parent | b9b0c3dfb44e929b4b9f7181e8ee16ea7cff8deb (diff) |
bmesh py api (some api changes and doc additions)
* remove 'select' and 'hide' from BMLoop
* remove BMesh.update
* add BMesh.normal_update(skip_hidden=False)
* add BMElemSet.index_update(), eg: bm.verts.index_update()
bmesh api
* BM_mesh_normals_update() now takes skip_hidden as an argument
(previously this was default behavior), however this isnt good when
using BMesh modifiers, where you want all normals to be recalculated.
* add bm_iter_itype_htype_map[], to get the iter type from a BMesh
iterator.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/bmesh/bmesh.h | 2 | ||||
-rw-r--r-- | source/blender/bmesh/bmesh_iterators.h | 9 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_iterators.c | 18 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_mesh.c | 14 | ||||
-rw-r--r-- | source/blender/editors/include/ED_view3d.h | 2 | ||||
-rw-r--r-- | source/blender/editors/mesh/bmesh_selecthistory.c | 2 | ||||
-rw-r--r-- | source/blender/editors/mesh/bmesh_tools.c | 2 | ||||
-rw-r--r-- | source/blender/editors/mesh/bmesh_utils.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_snap.c | 2 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_bevel.c | 2 | ||||
-rw-r--r-- | source/blender/modifiers/intern/MOD_edgesplit.c | 2 | ||||
-rw-r--r-- | source/blender/python/bmesh/bmesh_py_types.c | 120 | ||||
-rw-r--r-- | source/blender/python/bmesh/bmesh_py_types.h | 4 |
13 files changed, 123 insertions, 58 deletions
diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index 4535e7b8c58..dab70ac35bf 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -123,7 +123,7 @@ void BM_mesh_free(BMesh *bm); /* frees mesh, but not actual BMesh struct */ void BM_mesh_data_free(BMesh *bm); -void BM_mesh_normals_update(BMesh *bm); +void BM_mesh_normals_update(BMesh *bm, const short skip_hidden); /* Construction */ BMVert *BM_vert_create(BMesh *bm, const float co[3], const BMVert *example); diff --git a/source/blender/bmesh/bmesh_iterators.h b/source/blender/bmesh/bmesh_iterators.h index 08da4f9a949..ccbed3ecd01 100644 --- a/source/blender/bmesh/bmesh_iterators.h +++ b/source/blender/bmesh/bmesh_iterators.h @@ -49,7 +49,9 @@ */ /* these iterator over all elements of a specific - * type in the mesh.*/ + * type in the mesh. + * + * be sure to keep 'bm_iter_itype_htype_map' in sync with any changes */ typedef enum BMIterType { BM_VERTS_OF_MESH = 1, BM_EDGES_OF_MESH = 2, @@ -74,6 +76,11 @@ typedef enum BMIterType { BM_LOOPS_OF_EDGE = 14 } BMIterType; +#define BM_ITYPE_MAX 15 + +/* the iterator htype for each iterator */ +extern const char bm_iter_itype_htype_map[BM_ITYPE_MAX]; + #define BM_ITER(ele, iter, bm, itype, data) \ ele = BM_iter_new(iter, bm, itype, data); \ diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c index 281f42300ff..fb63ab36ef5 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.c +++ b/source/blender/bmesh/intern/bmesh_iterators.c @@ -32,6 +32,24 @@ #include "bmesh.h" #include "bmesh_private.h" +const char bm_iter_itype_htype_map[BM_ITYPE_MAX] = { + '\0', + BM_VERT, /* BM_VERTS_OF_MESH */ + BM_EDGE, /* BM_EDGES_OF_MESH */ + BM_FACE, /* BM_FACES_OF_MESH */ + BM_EDGE, /* BM_EDGES_OF_VERT */ + BM_FACE, /* BM_FACES_OF_VERT */ + BM_LOOP, /* BM_LOOPS_OF_VERT */ + BM_VERT, /* BM_VERTS_OF_EDGE */ + BM_FACE, /* BM_FACES_OF_EDGE */ + BM_VERT, /* BM_VERTS_OF_FACE */ + BM_EDGE, /* BM_EDGES_OF_FACE */ + BM_LOOP, /* BM_LOOPS_OF_FACE */ + BM_LOOP, /* BM_ALL_LOOPS_OF_FACE */ + BM_LOOP, /* BM_LOOPS_OF_LOOP */ + BM_LOOP /* BM_LOOPS_OF_EDGE */ +}; + /* * note, we have BM_vert_at_index/BM_edge_at_index/BM_face_at_index for arrays */ diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index a378ddaeabb..9621e593f3a 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -208,7 +208,7 @@ void BM_mesh_free(BMesh *bm) * */ -void BM_mesh_normals_update(BMesh *bm) +void BM_mesh_normals_update(BMesh *bm, const short skip_hidden) { BMVert *v; BMFace *f; @@ -225,7 +225,7 @@ void BM_mesh_normals_update(BMesh *bm) /* first, find out the largest face in mesh */ BM_ITER(f, &faces, bm, BM_FACES_OF_MESH, NULL) { - if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) + if (skip_hidden && BM_elem_flag_test(f, BM_ELEM_HIDDEN)) continue; if (f->len > maxlength) maxlength = f->len; @@ -239,7 +239,7 @@ void BM_mesh_normals_update(BMesh *bm) /* calculate all face normals */ BM_ITER(f, &faces, bm, BM_FACES_OF_MESH, NULL) { - if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) + if (skip_hidden && BM_elem_flag_test(f, BM_ELEM_HIDDEN)) continue; #if 0 /* UNUSED */ if (f->head.flag & BM_NONORMCALC) @@ -251,7 +251,7 @@ void BM_mesh_normals_update(BMesh *bm) /* Zero out vertex normals */ BM_ITER(v, &verts, bm, BM_VERTS_OF_MESH, NULL) { - if (BM_elem_flag_test(v, BM_ELEM_HIDDEN)) + if (skip_hidden && BM_elem_flag_test(v, BM_ELEM_HIDDEN)) continue; zero_v3(v->no); @@ -280,7 +280,7 @@ void BM_mesh_normals_update(BMesh *bm) /* add weighted face normals to vertices */ BM_ITER(f, &faces, bm, BM_FACES_OF_MESH, NULL) { - if (BM_elem_flag_test(f, BM_ELEM_HIDDEN)) + if (skip_hidden && BM_elem_flag_test(f, BM_ELEM_HIDDEN)) continue; BM_ITER(l, &loops, bm, BM_LOOPS_OF_FACE, f) { @@ -310,7 +310,7 @@ void BM_mesh_normals_update(BMesh *bm) /* normalize the accumulated vertex normals */ BM_ITER(v, &verts, bm, BM_VERTS_OF_MESH, NULL) { - if (BM_elem_flag_test(v, BM_ELEM_HIDDEN)) + if (skip_hidden && BM_elem_flag_test(v, BM_ELEM_HIDDEN)) continue; if (normalize_v3(v->no) == 0.0f) { @@ -473,7 +473,7 @@ void bmesh_end_edit(BMesh *bm, int flag) bm->opflag = 0; /* compute normals, clear temp flags and flush selections */ - BM_mesh_normals_update(bm); + BM_mesh_normals_update(bm, TRUE); BM_mesh_select_mode_flush(bm); } diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 2d4e267ba80..9ef4bc1cbd5 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -157,7 +157,7 @@ void ED_view3d_global_to_vector(struct RegionView3D *rv3d, const float coord[3], /** * Calculate the view transformation matrix from RegionView3D input. - * The resulting matrix is equivilent to RegionView3D.viewinv + * The resulting matrix is equivalent to RegionView3D.viewinv * @param mat The view 4x4 transformation matrix to calculate. * @param ofs The view offset, normally from RegionView3D.ofs. * @param quat The view rotation, quaternion normally from RegionView3D.viewquat. diff --git a/source/blender/editors/mesh/bmesh_selecthistory.c b/source/blender/editors/mesh/bmesh_selecthistory.c index a242356f1ab..ed3bd0c8a87 100644 --- a/source/blender/editors/mesh/bmesh_selecthistory.c +++ b/source/blender/editors/mesh/bmesh_selecthistory.c @@ -30,7 +30,7 @@ #include "BKE_tessmesh.h" -/* these wrap equivilent bmesh functions. I'm in two minds of it we should +/* these wrap equivalent bmesh functions. I'm in two minds of it we should * just use the bm functions directly; on the one hand, there's no real * need (at the moment) to wrap them, but on the other hand having these * wrapped avoids a confusing mess of mixing BM_ and EDBM_ namespaces. */ diff --git a/source/blender/editors/mesh/bmesh_tools.c b/source/blender/editors/mesh/bmesh_tools.c index 5225b704a7f..972236ab411 100644 --- a/source/blender/editors/mesh/bmesh_tools.c +++ b/source/blender/editors/mesh/bmesh_tools.c @@ -3262,7 +3262,7 @@ static int mesh_separate_selected(Main *bmain, Scene *scene, Base *editbase, wmO EDBM_CallOpf(em, wmop, "del geom=%hvef context=%i", BM_ELEM_SELECT, DEL_VERTS); - BM_mesh_normals_update(bmnew); + BM_mesh_normals_update(bmnew, TRUE); BMO_op_callf(bmnew, "bmesh_to_mesh mesh=%p object=%p notesselation=%b", basenew->object->data, basenew->object, TRUE); diff --git a/source/blender/editors/mesh/bmesh_utils.c b/source/blender/editors/mesh/bmesh_utils.c index 0f49ffa78e8..da1904cf11a 100644 --- a/source/blender/editors/mesh/bmesh_utils.c +++ b/source/blender/editors/mesh/bmesh_utils.c @@ -50,7 +50,7 @@ void EDBM_RecalcNormals(BMEditMesh *em) { - BM_mesh_normals_update(em->bm); + BM_mesh_normals_update(em->bm, TRUE); } void EDBM_ClearMesh(BMEditMesh *em) diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c index 978d32be48a..c5e0572154a 100644 --- a/source/blender/editors/space_view3d/view3d_snap.c +++ b/source/blender/editors/space_view3d/view3d_snap.c @@ -102,7 +102,7 @@ static void special_transvert_update(Object *obedit) if (obedit->type==OB_MESH) { Mesh *me= obedit->data; - BM_mesh_normals_update(me->edit_btmesh->bm); // does face centers too + BM_mesh_normals_update(me->edit_btmesh->bm, TRUE); // does face centers too } else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) { Curve *cu= obedit->data; diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index 8aefd928858..92584800f98 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -121,7 +121,7 @@ static DerivedMesh *applyModifier(ModifierData *md, struct Object *ob, em = DM_to_editbmesh(ob, dm, NULL, FALSE); bm = em->bm; - BM_mesh_normals_update(bm); + BM_mesh_normals_update(bm, FALSE); BMO_push(bm, NULL); if (bmd->lim_flags & BME_BEVEL_ANGLE) { diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index 14b54be8be1..1e275862b5c 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -69,7 +69,7 @@ static DerivedMesh *doEdgeSplit(DerivedMesh *dm, EdgeSplitModifierData *emd, Obj em = DM_to_editbmesh(ob, dm, NULL, FALSE); bm = em->bm; - BM_mesh_normals_update(bm); + BM_mesh_normals_update(bm, FALSE); BMO_push(bm, NULL); if (emd->flags & MOD_EDGESPLIT_FROMANGLE) { diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 08097a2dc57..22eded1d11b 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -159,7 +159,7 @@ static int bpy_bm_elem_index_set(BPy_BMElem *self, PyObject *value, void *UNUSED return -1; } else { - BM_elem_index_set(self->ele, param); + BM_elem_index_set(self->ele, param); /* set_dirty! */ /* when setting the index assume its set invalid */ if (self->ele->htype & (BM_VERT | BM_EDGE | BM_FACE)) { @@ -474,8 +474,9 @@ static PyGetSetDef bpy_bmface_getseters[] = { static PyGetSetDef bpy_bmloop_getseters[] = { /* generic */ - {(char *)"select", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_select_doc, (void *)BM_ELEM_SELECT}, - {(char *)"hide", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_hide_doc, (void *)BM_ELEM_SELECT}, + // flags are available but not used for loops. + // {(char *)"select", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_select_doc, (void *)BM_ELEM_SELECT}, + // {(char *)"hide", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_hide_doc, (void *)BM_ELEM_SELECT}, {(char *)"tag", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_tag_doc, (void *)BM_ELEM_TAG}, {(char *)"index", (getter)bpy_bm_elem_index_get, (setter)bpy_bm_elem_index_set, (char *)bpy_bm_elem_index_doc, NULL}, @@ -535,49 +536,27 @@ static PyObject *bpy_bmesh_select_flush(BPy_BMesh *self, PyObject *value) Py_RETURN_NONE; } -PyDoc_STRVAR(bpy_bmesh_update_doc, -".. method:: update(index=False, normals=False)\n" +PyDoc_STRVAR(bpy_bmesh_normal_update_doc, +".. method:: normal_update(skip_hidden=False)\n" "\n" -" Update mesh data.\n" +" Update mesh normals.\n" "\n" -" :arg normals: When True will re-calculate normals for verts and faces.\n" -" :type normals: boolean\n" +" :arg skip_hidden: When True hidden elements are ignored.\n" +" :type skip_hidden: boolean\n" ); -static PyObject *bpy_bmesh_update(BPy_BMElem *self, PyObject *args, PyObject *kw) +static PyObject *bpy_bmesh_normal_update(BPy_BMElem *self, PyObject *args) { - static const char *kwlist[] = {"normals", "index", NULL}; - int do_normals = FALSE; - - PyObject *index_flags = NULL; - int do_index_hflag = 0; + int skip_hidden = FALSE; BPY_BM_CHECK_OBJ(self); - if (!PyArg_ParseTupleAndKeywords(args, kw, - "|iO:update", - (char **)kwlist, - &do_normals, &index_flags)) - { + if (!PyArg_ParseTuple(args, "|i:normal_update", &skip_hidden)) { return NULL; } - if (index_flags) { - if (PyC_FlagSet_ToBitfield(bpy_bm_htype_vert_edge_face_flags, index_flags, - &do_index_hflag, "bm.update(index=...)") == -1) - { - return NULL; - } - } - - if (do_normals) { - BM_mesh_normals_update(self->bm); - } - - if (do_index_hflag) { - BM_mesh_elem_index_ensure(self->bm, (char)do_index_hflag); - } + BM_mesh_normals_update(self->bm, skip_hidden); Py_RETURN_NONE; } @@ -589,7 +568,7 @@ PyDoc_STRVAR(bpy_bmesh_transform_doc, " Transform the mesh (optionally filtering flagged data only).\n" "\n" " :arg matrix: transform matrix.\n" -" :type matrix: 4x4 :class:`mathutils.Matrix`" +" :type matrix: 4x4 :class:`mathutils.Matrix`\n" " :arg filter: set of values in ('SELECT', 'HIDE', 'SEAM', 'SMOOTH', 'TAG').\n" " :type filter: set\n" ); @@ -1195,7 +1174,7 @@ static PyObject *bpy_bmface_seq_remove(BPy_BMElemSeq *self, BPy_BMFace *value) PyDoc_STRVAR(bpy_bmelemseq_remove_doc, -".. method:: remove()\n" +".. method:: remove(elem)\n" "\n" " Remove a vert/edge/face.\n" ); @@ -1215,10 +1194,69 @@ static PyObject *bpy_bmelemseq_remove(BPy_BMElemSeq *self, PyObject *value) } } +PyDoc_STRVAR(bpy_bmelemseq_index_update_doc, +".. method:: index_update()\n" +"\n" +" Initialize the index values of this sequence.\n" +"\n" +" This is the equivalent of looping over all elements and assigning the index values.\n" +"\n" +" .. code-block:: python\n" +"\n" +" for index, ele in enumerate(sequence):\n" +" ele.index = index\n" +"\n" +" .. note::\n" +"\n" +" Running this on sequences besides :class:`BMesh.verts`, :class:`BMesh.edges`, :class:`BMesh.faces`\n" +" works but wont result in each element having a valid index, insted its order in the sequence will be set.\n" +); +static PyObject *bpy_bmelemseq_index_update(BPy_BMElemSeq *self) +{ + BMesh *bm = self->bm; + + BPY_BM_CHECK_OBJ(self); + + switch ((BMIterType)self->itype) { + case BM_VERTS_OF_MESH: + BM_mesh_elem_index_ensure(self->bm, BM_VERT); + break; + case BM_EDGES_OF_MESH: + BM_mesh_elem_index_ensure(self->bm, BM_EDGE); + break; + case BM_FACES_OF_MESH: + BM_mesh_elem_index_ensure(self->bm, BM_FACE); + break; + default: + { + BMIter iter; + BMHeader *ele; + int index = 0; + const char htype = bm_iter_itype_htype_map[self->itype]; + + BM_ITER_BPY_BM_SEQ(ele, &iter, self) { + BM_elem_index_set(ele, index); /* set_dirty! */ + index++; + } + + if (htype & (BM_VERT | BM_EDGE | BM_FACE)) { + /* since this isnt the normal vert/edge/face loops, + * we're setting dirty values here. so tag as dirty. */ + bm->elem_index_dirty |= htype; + } + + break; + } + } + + Py_RETURN_NONE; +} + + static struct PyMethodDef bpy_bmesh_methods[] = { {"select_flush_mode", (PyCFunction)bpy_bmesh_select_flush_mode, METH_NOARGS, bpy_bmesh_select_flush_mode_doc}, {"select_flush", (PyCFunction)bpy_bmesh_select_flush, METH_O, bpy_bmesh_select_flush_doc}, - {"update", (PyCFunction)bpy_bmesh_update, METH_VARARGS|METH_KEYWORDS, bpy_bmesh_update_doc}, + {"normal_update", (PyCFunction)bpy_bmesh_normal_update, METH_VARARGS, bpy_bmesh_normal_update_doc}, {"transform", (PyCFunction)bpy_bmesh_transform, METH_VARARGS|METH_KEYWORDS, bpy_bmesh_transform_doc}, {NULL, NULL, 0, NULL} }; @@ -1263,17 +1301,15 @@ static struct PyMethodDef bpy_bmloop_methods[] = { static struct PyMethodDef bpy_bmelemseq_methods[] = { {"new", (PyCFunction)bpy_bmelemseq_new, METH_VARARGS, bpy_bmelemseq_new_doc}, {"remove", (PyCFunction)bpy_bmelemseq_remove, METH_O, bpy_bmelemseq_remove_doc}, + + /* odd function, initializes index values */ + {"index_update", (PyCFunction)bpy_bmelemseq_index_update, METH_NOARGS, bpy_bmelemseq_index_update_doc}, {NULL, NULL, 0, NULL} }; /* Sequences * ========= */ -#define BM_ITER_BPY_BM_SEQ(ele, iter, bpy_bmelemseq) \ - BM_ITER(ele, iter, (bpy_bmelemseq)->bm, (bpy_bmelemseq)->itype,\ - (bpy_bmelemseq)->py_ele ? ((BPy_BMElem *)(bpy_bmelemseq)->py_ele)->ele : NULL) - - static PyTypeObject *bpy_bm_itype_as_pytype(const char itype) { /* should cover all types */ diff --git a/source/blender/python/bmesh/bmesh_py_types.h b/source/blender/python/bmesh/bmesh_py_types.h index 67a276f3f80..05a36ee9897 100644 --- a/source/blender/python/bmesh/bmesh_py_types.h +++ b/source/blender/python/bmesh/bmesh_py_types.h @@ -140,4 +140,8 @@ void *BPy_BMElem_PySeq_As_Array(BMesh **r_bm, PyObject *seq, Py_ssize_t min, Py_ #define BPY_BM_CHECK_OBJ(obj) if (bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1) { return NULL; } (void)NULL #define BPY_BM_CHECK_INT(obj) if (bpy_bm_generic_valid_check((BPy_BMGeneric *)obj) == -1) { return -1; } (void)NULL +#define BM_ITER_BPY_BM_SEQ(ele, iter, bpy_bmelemseq) \ + BM_ITER(ele, iter, (bpy_bmelemseq)->bm, (bpy_bmelemseq)->itype,\ + (bpy_bmelemseq)->py_ele ? ((BPy_BMElem *)(bpy_bmelemseq)->py_ele)->ele : NULL) + #endif /* __BMESH_TYPES_H__ */ |