Exemplo 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;
}
Exemplo n.º 2
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;
	bool edge_exists = true;
	BPy_BMEdge *py_edge_example = NULL;

	float *coords;
	int ncoords = 0;

	BMesh *bm;
	BMFace *f_new = NULL;
	BMLoop *l_new = NULL;
	BMLoop *l_a, *l_b;

	if (!PyArg_ParseTupleAndKeywords(
	        args, kw,
	        "O!O!O!|OO&O!:face_split", (char **)kwlist,
	        &BPy_BMFace_Type, &py_face,
	        &BPy_BMVert_Type, &py_vert_a,
	        &BPy_BMVert_Type, &py_vert_b,
	        &py_coords,
	        PyC_ParseBool, &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 ((l_a = BM_face_vert_share_loop(py_face->f, py_vert_a->v)) &&
	    (l_b = BM_face_vert_share_loop(py_face->f, py_vert_b->v)))
	{
		/* pass */
	}
	else {
		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;
		}
	}
	else {
		if (BM_loop_is_adjacent(l_a, l_b)) {
			PyErr_SetString(PyExc_ValueError,
			                "face_split(...): verts are adjacent in the face");
			return NULL;
		}
	}

	/* --- main function body --- */
	bm = py_face->bm;

	if (ncoords) {
		f_new = BM_face_split_n(bm, py_face->f,
		                        l_a, l_b,
		                        (float (*)[3])coords, ncoords,
		                        &l_new, py_edge_example ? py_edge_example->e : NULL);
		PyMem_Free(coords);
	}
	else {
		f_new = BM_face_split(bm, py_face->f,
		                      l_a, l_b,
		                      &l_new, py_edge_example ? py_edge_example->e : NULL, edge_exists);
	}

	if (f_new && l_new) {
		PyObject *ret = PyTuple_New(2);
		PyTuple_SET_ITEMS(ret,
		        BPy_BMFace_CreatePyObject(bm, f_new),
		        BPy_BMLoop_CreatePyObject(bm, l_new));
		return ret;
	}
	else {
		PyErr_SetString(PyExc_ValueError,
		                "face_split(...): couldn't split the face, internal error");
		return NULL;
	}
}