Ejemplo n.º 1
0
/* 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;
}
Ejemplo n.º 2
0
/* 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;
}
Ejemplo n.º 3
0
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;
	}
}