/* connects face with smallest len, which I think should always be correct for * edge subdivision */ static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v_a, BMVert *v_b, BMFace **r_f_new) { BMLoop *l_a, *l_b; BMFace *f; /* this isn't the best thing in the world. it doesn't handle cases where there's * multiple faces yet. that might require a convexity test to figure out which * face is "best" and who knows what for non-manifold conditions. * * note: we allow adjacent here, since theres no chance this happens. */ f = BM_vert_pair_share_face_by_len(v_a, v_b, &l_a, &l_b, true); if (f) { BMFace *f_new; BMLoop *l_new; BLI_assert(!BM_loop_is_adjacent(l_a, l_b)); f_new = BM_face_split(bm, f, l_a, l_b, &l_new, NULL, false); if (r_f_new) *r_f_new = f_new; return l_new ? l_new->e : NULL; } return NULL; }
/* connects face with smallest len, which I think should always be correct for * edge subdivision */ static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **r_f_new) { BMIter iter, iter2; BMVert *v; BMLoop *l_new; BMFace *f, *f_cur = NULL; /* this isn't the best thing in the world. it doesn't handle cases where there's * multiple faces yet. that might require a convexity test to figure out which * face is "best" and who knows what for non-manifold conditions. */ for (f = BM_iter_new(&iter, bm, BM_FACES_OF_VERT, v1); f; f = BM_iter_step(&iter)) { for (v = BM_iter_new(&iter2, bm, BM_VERTS_OF_FACE, f); v; v = BM_iter_step(&iter2)) { if (v == v2) { if (!f_cur || f->len < f_cur->len) f_cur = f; } } } if (f_cur) { f = BM_face_split(bm, f_cur, v1, v2, &l_new, NULL, false); if (r_f_new) *r_f_new = f; return l_new ? l_new->e : NULL; } return NULL; }
static PyObject *bpy_bm_utils_face_split(PyObject *UNUSED(self), PyObject *args, PyObject *kw) { static const char *kwlist[] = {"face", "vert_a", "vert_b", "coords", "use_exist", "example", NULL}; BPy_BMFace *py_face; BPy_BMVert *py_vert_a; BPy_BMVert *py_vert_b; /* optional */ PyObject *py_coords = NULL; int edge_exists = TRUE; BPy_BMEdge *py_edge_example = NULL; float *coords; int ncoords = 0; BMesh *bm; BMFace *f_new = NULL; BMLoop *l_new = NULL; if (!PyArg_ParseTupleAndKeywords(args, kw, "O!O!O!|OiO!:face_split", (char **)kwlist, &BPy_BMFace_Type, &py_face, &BPy_BMVert_Type, &py_vert_a, &BPy_BMVert_Type, &py_vert_b, &py_coords, &edge_exists, &BPy_BMEdge_Type, &py_edge_example)) { return NULL; } BPY_BM_CHECK_OBJ(py_face); BPY_BM_CHECK_OBJ(py_vert_a); BPY_BM_CHECK_OBJ(py_vert_b); if (py_edge_example) { BPY_BM_CHECK_OBJ(py_edge_example); } /* 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; } if (py_coords) { ncoords = mathutils_array_parse_alloc_v(&coords, 3, py_coords, "face_split(...): "); if (ncoords == -1) { return NULL; } } /* --- main function body --- */ bm = py_face->bm; if (ncoords) { f_new = BM_face_split_n(bm, py_face->f, py_vert_a->v, py_vert_b->v, (float (*)[3])coords, ncoords, &l_new, py_edge_example ? py_edge_example->e : NULL); } else { f_new = BM_face_split(bm, py_face->f, py_vert_a->v, py_vert_b->v, &l_new, py_edge_example ? py_edge_example->e : NULL, edge_exists); } 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; } }