/** * Fill in an edge array from a vertex array (connected polygon loop). * * \returns false if any edges aren't found. */ bool BM_edges_from_verts(BMEdge **edge_arr, BMVert **vert_arr, const int len) { int i, i_prev = len - 1; for (i = 0; i < len; i++) { edge_arr[i_prev] = BM_edge_exists(vert_arr[i_prev], vert_arr[i]); if (edge_arr[i_prev] == NULL) { return false; } i_prev = i; } return true; }
static PyObject *bpy_bm_utils_vert_splice(PyObject *UNUSED(self), PyObject *args) { BPy_BMVert *py_vert; BPy_BMVert *py_vert_target; BMesh *bm; bool ok; if (!PyArg_ParseTuple(args, "O!O!:vert_splice", &BPy_BMVert_Type, &py_vert, &BPy_BMVert_Type, &py_vert_target)) { return NULL; } BPY_BM_CHECK_OBJ(py_vert); BPY_BM_CHECK_OBJ(py_vert_target); bm = py_vert->bm; BPY_BM_CHECK_SOURCE_OBJ(bm, "vert_splice", py_vert_target); if (py_vert->v == py_vert_target->v) { PyErr_SetString(PyExc_ValueError, "vert_splice(...): vert arguments match"); return NULL; } if (BM_edge_exists(py_vert->v, py_vert_target->v)) { PyErr_SetString(PyExc_ValueError, "vert_splice(...): verts can't share an edge"); return NULL; } if (BM_vert_pair_share_face_check(py_vert->v, py_vert_target->v)) { PyErr_SetString(PyExc_ValueError, "vert_splice(...): verts can't share a face"); return NULL; } /* should always succeed */ ok = BM_vert_splice(bm, py_vert_target->v, py_vert->v); BLI_assert(ok == true); UNUSED_VARS_NDEBUG(ok); Py_RETURN_NONE; }
/** * Create an ngon from an array of sorted verts * * Special features this has over other functions. * - Optionally calculate winding based on surrounding edges. * - Optionally create edges between vertices. * - Uses verts so no need to find edges (handy when you only have verts) */ BMFace *BM_face_create_ngon_verts( BMesh *bm, BMVert **vert_arr, const int len, const BMFace *f_example, const eBMCreateFlag create_flag, const bool calc_winding, const bool create_edges) { BMEdge **edge_arr = BLI_array_alloca(edge_arr, len); uint winding[2] = {0, 0}; int i, i_prev = len - 1; BMVert *v_winding[2] = {vert_arr[i_prev], vert_arr[0]}; BLI_assert(len > 2); for (i = 0; i < len; i++) { if (create_edges) { edge_arr[i] = BM_edge_create(bm, vert_arr[i_prev], vert_arr[i], NULL, BM_CREATE_NO_DOUBLE); } else { edge_arr[i] = BM_edge_exists(vert_arr[i_prev], vert_arr[i]); if (edge_arr[i] == NULL) { return NULL; } } if (calc_winding) { /* the edge may exist already and be attached to a face * in this case we can find the best winding to use for the new face */ if (edge_arr[i]->l) { BMVert *test_v1, *test_v2; /* we want to use the reverse winding to the existing order */ BM_edge_ordered_verts(edge_arr[i], &test_v2, &test_v1); winding[(vert_arr[i_prev] == test_v2)]++; BLI_assert(vert_arr[i_prev] == test_v2 || vert_arr[i_prev] == test_v1); } } i_prev = i; } /* --- */ if (calc_winding) { if (winding[0] < winding[1]) { winding[0] = 1; winding[1] = 0; } else { winding[0] = 0; winding[1] = 1; } } else { winding[0] = 0; winding[1] = 1; } /* --- */ /* create the face */ return BM_face_create_ngon( bm, v_winding[winding[0]], v_winding[winding[1]], edge_arr, len, f_example, create_flag); }