diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-02-23 14:29:04 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-02-23 14:29:04 +0400 |
commit | 303497152027fd68006e130c69943adcdff4aa08 (patch) | |
tree | 7d9d7b4fbafa2be2a59e20f4652408eb654c1499 | |
parent | c3e192dcaeebae3de9352907ade308221f3dda5f (diff) |
bmesh py api functions:
bmesh.utils.vert_collapse_edge, vert_collapse_faces, vert_dissolve, face_split
-rw-r--r-- | source/blender/python/bmesh/bmesh_py_types.c | 2 | ||||
-rw-r--r-- | source/blender/python/bmesh/bmesh_py_utils.c | 244 |
2 files changed, 237 insertions, 9 deletions
diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index 49380e363ea..515a5f05f3b 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -1345,7 +1345,7 @@ static int bpy_bm_seq_contains(BPy_BMElemSeq *self, PyObject *value) if (value_bm_ele->bm == self->bm) { BMHeader *ele, *ele_test = value_bm_ele->ele; BMIter iter; - BM_ITER(ele, &iter, self->bm, BM_VERTS_OF_MESH, NULL) { + BM_ITER_BPY_BM_SEQ(ele, &iter, self) { if (ele == ele_test) { return 1; } diff --git a/source/blender/python/bmesh/bmesh_py_utils.c b/source/blender/python/bmesh/bmesh_py_utils.c index 5e8464a30ef..88b875cc489 100644 --- a/source/blender/python/bmesh/bmesh_py_utils.c +++ b/source/blender/python/bmesh/bmesh_py_utils.c @@ -30,8 +30,6 @@ * Utility functions for operating on 'bmesh.types' */ - - #include <Python.h> #include "bmesh.h" @@ -42,8 +40,163 @@ #include "bmesh_py_utils.h" /* own include */ +PyDoc_STRVAR(bpy_bm_utils_vert_collapse_edge_doc, +".. method:: vert_collapse_edge(vert, edge)\n" +"\n" +" Split an edge, return the newly created data.\n" +"\n" +" :arg vert: The vert that will be collapsed.\n" +" :type vert: :class:`bmesh.tupes.BMVert`\n" +" :arg edge: The edge to collapse into.\n" +" :type edge: :class:`bmesh.tupes.BMEdge`\n" +" :return: The resulting edge from the collapse operation.\n" +" :rtype: :class:`bmesh.tupes.BMEdge`\n" +); +static PyObject *bpy_bm_utils_vert_collapse_edge(PyObject *UNUSED(self), PyObject *args) +{ + BPy_BMEdge *py_edge; + BPy_BMVert *py_vert; + + BMesh *bm; + BMEdge *e_new = NULL; + + if (!PyArg_ParseTuple(args, "O!O!:vert_collapse_edge", + &BPy_BMVert_Type, &py_vert, + &BPy_BMEdge_Type, &py_edge)) + { + return NULL; + } + + BPY_BM_CHECK_OBJ(py_edge); + BPY_BM_CHECK_OBJ(py_vert); + + /* this doubles for checking that the verts are in the same mesh */ + if (!(py_edge->e->v1 == py_vert->v || + py_edge->e->v2 == py_vert->v)) + { + PyErr_SetString(PyExc_ValueError, + "vert_collapse_edge(vert, edge): the vertex is not found in the edge"); + return NULL; + } + + if (BM_vert_edge_count(py_vert->v) > 2) { + PyErr_SetString(PyExc_ValueError, + "vert_collapse_edge(vert, edge): vert has more then 2 connected edges"); + return NULL; + } + + bm = py_edge->bm; + + e_new = BM_vert_collapse_edge(bm, py_edge->e, py_vert->v); + + if (e_new) { + return BPy_BMEdge_CreatePyObject(bm, e_new); + } + else { + PyErr_SetString(PyExc_ValueError, + "vert_collapse_edge(vert, edge): no new edge created, internal error"); + return NULL; + } +} + + +PyDoc_STRVAR(bpy_bm_utils_vert_collapse_faces_doc, +".. method:: vert_collapse_faces(vert, edge, fac, join_faces)\n" +"\n" +" Split an edge, return the newly created data.\n" +"\n" +" :arg vert: The vert that will be collapsed.\n" +" :type vert: :class:`bmesh.tupes.BMVert`\n" +" :arg edge: The edge to collapse into.\n" +" :type edge: :class:`bmesh.tupes.BMEdge`\n" +" :arg fac: The factor to use when merging customdata [0 - 1].\n" +" :type fac: float\n" +" :return: The resulting edge from the collapse operation.\n" +" :rtype: :class:`bmesh.tupes.BMEdge`\n" +); +static PyObject *bpy_bm_utils_vert_collapse_faces(PyObject *UNUSED(self), PyObject *args) +{ + BPy_BMEdge *py_edge; + BPy_BMVert *py_vert; + + float fac; + int do_join_faces; + + BMesh *bm; + BMEdge *e_new = NULL; + + if (!PyArg_ParseTuple(args, "O!O!fi:vert_collapse_faces", + &BPy_BMVert_Type, &py_vert, + &BPy_BMEdge_Type, &py_edge, + &fac, &do_join_faces)) + { + return NULL; + } + + BPY_BM_CHECK_OBJ(py_edge); + BPY_BM_CHECK_OBJ(py_vert); + + /* this doubles for checking that the verts are in the same mesh */ + if (!(py_edge->e->v1 == py_vert->v || + py_edge->e->v2 == py_vert->v)) + { + PyErr_SetString(PyExc_ValueError, + "vert_collapse_faces(vert, edge): the vertex is not found in the edge"); + return NULL; + } + + if (BM_vert_edge_count(py_vert->v) > 2) { + PyErr_SetString(PyExc_ValueError, + "vert_collapse_faces(vert, edge): vert has more then 2 connected edges"); + return NULL; + } + + bm = py_edge->bm; + + e_new = BM_vert_collapse_faces(bm, py_edge->e, py_vert->v, CLAMPIS(fac, 0.0f, 1.0f), do_join_faces); + + if (e_new) { + return BPy_BMEdge_CreatePyObject(bm, e_new); + } + else { + PyErr_SetString(PyExc_ValueError, + "vert_collapse_edge(vert, edge): no new edge created, internal error"); + return NULL; + } +} + +PyDoc_STRVAR(bpy_bm_utils_vert_dissolve_doc, +".. method:: vert_dissolve(vert)\n" +"\n" +" Dissolve this vertex (will be removed).\n" +"\n" +" :arg vert: The vert to be dissolved.\n" +" :type vert: :class:`bmesh.tupes.BMVert`\n" +" :return: True when the vertex dissolve is successful.\n" +" :rtype: bool\n" +); +static PyObject *bpy_bm_utils_vert_dissolve(PyObject *UNUSED(self), PyObject *args) +{ + BPy_BMVert *py_vert; + + BMesh *bm; + + if (!PyArg_ParseTuple(args, "O!:vert_dissolve", + &BPy_BMVert_Type, &py_vert)) + { + return NULL; + } + + BPY_BM_CHECK_OBJ(py_vert); + + bm = py_vert->bm; + + return PyBool_FromLong((BM_vert_dissolve(bm, py_vert->v))); +} + + PyDoc_STRVAR(bpy_bm_utils_edge_split_doc, -".. method:: edge_split(vert, edge, fac)\n" +".. method:: edge_split(edge, vert, fac)\n" "\n" " Split an edge, return the newly created data.\n" "\n" @@ -51,12 +204,11 @@ PyDoc_STRVAR(bpy_bm_utils_edge_split_doc, " :type edge: :class:`bmesh.tupes.BMEdge`\n" " :arg vert: One of the verts on the edge, defines the split direction.\n" " :type vert: :class:`bmesh.tupes.BMVert`\n" -" :arg fac: The point on the edge where the new vert will be created.\n" +" :arg fac: The point on the edge where the new vert will be created [0 - 1].\n" " :type fac: float\n" " :return: The newly created (edge, vert) pair.\n" " :rtype: tuple\n" ); - static PyObject *bpy_bm_utils_edge_split(PyObject *UNUSED(self), PyObject *args) { BPy_BMEdge *py_edge; @@ -78,6 +230,7 @@ static PyObject *bpy_bm_utils_edge_split(PyObject *UNUSED(self), PyObject *args) BPY_BM_CHECK_OBJ(py_edge); BPY_BM_CHECK_OBJ(py_vert); + /* this doubles for checking that the verts are in the same mesh */ if (!(py_edge->e->v1 == py_vert->v || py_edge->e->v2 == py_vert->v)) { @@ -88,7 +241,7 @@ static PyObject *bpy_bm_utils_edge_split(PyObject *UNUSED(self), PyObject *args) bm = py_edge->bm; - v_new = BM_edge_split(bm, py_edge->e, py_vert->v, &e_new, fac); + v_new = BM_edge_split(bm, py_edge->e, py_vert->v, &e_new, CLAMPIS(fac, 0.0f, 1.0f)); if (v_new && e_new) { PyObject *ret = PyTuple_New(2); @@ -103,9 +256,84 @@ static PyObject *bpy_bm_utils_edge_split(PyObject *UNUSED(self), PyObject *args) } } +PyDoc_STRVAR(bpy_bm_utils_face_split_doc, +".. method:: face_split(vert, vert_a, vert_b, )\n" +"\n" +" Split an edge, return the newly created data.\n" +"\n" +" :arg edge: The edge to split.\n" +" :type edge: :class:`bmesh.tupes.BMEdge`\n" +" :arg vert: One of the verts on the edge, defines the split direction.\n" +" :type vert: :class:`bmesh.tupes.BMVert`\n" +" :arg fac: The point on the edge where the new vert will be created [0 - 1].\n" +" :type fac: float\n" +" :return: The newly created (edge, vert) pair.\n" +" :rtype: tuple\n" +); +static PyObject *bpy_bm_utils_face_split(PyObject *UNUSED(self), PyObject *args) +{ + BPy_BMFace *py_face; + BPy_BMVert *py_vert_a; + BPy_BMVert *py_vert_b; + float fac; + + BMesh *bm; + BMFace *f_new = NULL; + BMLoop *l_new = NULL; + + if (!PyArg_ParseTuple(args, "O!O!:face_split", + &BPy_BMFace_Type, &py_face, + &BPy_BMVert_Type, &py_vert_a, + &BPy_BMVert_Type, &py_vert_b, + &fac)) + { + return NULL; + } + + BPY_BM_CHECK_OBJ(py_face); + BPY_BM_CHECK_OBJ(py_vert_a); + BPY_BM_CHECK_OBJ(py_vert_b); + + /* this doubles for checking that the verts are in the same mesh */ + if (BM_vert_in_face(py_face->f, py_vert_a->v) == FALSE || + BM_vert_in_face(py_face->f, py_vert_b->v) == FALSE) + { + PyErr_SetString(PyExc_ValueError, + "face_split(...): one of the verts passed is not found in the face"); + return NULL; + } + + if (py_vert_a->v == py_vert_b->v) { + PyErr_SetString(PyExc_ValueError, + "face_split(...): vert arguments must differ"); + return NULL; + } + + bm = py_face->bm; + + f_new = BM_face_split(bm, py_face->f, py_vert_a->v, py_vert_a->v, &l_new, NULL); + + if (f_new && l_new) { + PyObject *ret = PyTuple_New(2); + PyTuple_SET_ITEM(ret, 0, BPy_BMFace_CreatePyObject(bm, f_new)); + PyTuple_SET_ITEM(ret, 1, BPy_BMLoop_CreatePyObject(bm, l_new)); + return ret; + } + else { + PyErr_SetString(PyExc_ValueError, + "face_split(...): couldn't split the face, internal error"); + return NULL; + } +} + + static struct PyMethodDef BPy_BM_utils_methods[] = { - {"edge_split", (PyCFunction)bpy_bm_utils_edge_split, METH_VARARGS, bpy_bm_utils_edge_split_doc}, - {NULL, NULL, 0, NULL} + {"vert_collapse_edge", (PyCFunction)bpy_bm_utils_vert_collapse_edge, METH_VARARGS, bpy_bm_utils_vert_collapse_edge_doc}, + {"vert_collapse_faces", (PyCFunction)bpy_bm_utils_vert_collapse_faces, METH_VARARGS, bpy_bm_utils_vert_collapse_faces_doc}, + {"vert_dissolve", (PyCFunction)bpy_bm_utils_vert_dissolve, METH_VARARGS, bpy_bm_utils_vert_dissolve_doc}, + {"edge_split", (PyCFunction)bpy_bm_utils_edge_split, METH_VARARGS, bpy_bm_utils_edge_split_doc}, + {"face_split", (PyCFunction)bpy_bm_utils_face_split, METH_VARARGS, bpy_bm_utils_face_split_doc}, + {NULL, NULL, 0, NULL} }; PyDoc_STRVAR(BPy_BM_doc, |