static void bm_subdivide_multicut(
        BMesh *bm, BMEdge *edge, const SubDParams *params,
        BMVert *v_a, BMVert *v_b)
{
	BMEdge *eed = edge, *e_new, e_tmp = *edge;
	BMVert *v, v1_tmp = *edge->v1, v2_tmp = *edge->v2, *v1 = edge->v1, *v2 = edge->v2;
	int i, numcuts = params->numcuts;

	e_tmp.v1 = &v1_tmp;
	e_tmp.v2 = &v2_tmp;
	
	for (i = 0; i < numcuts; i++) {
		v = subdivide_edge_num(bm, eed, &e_tmp, i, params->numcuts, params, v_a, v_b, &e_new);

		BMO_elem_flag_enable(bm, v, SUBD_SPLIT | ELE_SPLIT);
		BMO_elem_flag_enable(bm, eed, SUBD_SPLIT | ELE_SPLIT);
		BMO_elem_flag_enable(bm, e_new, SUBD_SPLIT | ELE_SPLIT);

		BM_CHECK_ELEMENT(v);
		if (v->e) BM_CHECK_ELEMENT(v->e);
		if (v->e && v->e->l) BM_CHECK_ELEMENT(v->e->l->f);
	}
	
	alter_co(v1, &e_tmp, params, 0, &v1_tmp, &v2_tmp);
	alter_co(v2, &e_tmp, params, 1.0, &v1_tmp, &v2_tmp);
}
示例#2
0
/* results in new vertex with correct coordinate, vertex normal and weight group info */
static BMVert *bm_subdivide_edge_addvert(BMesh *bm, BMEdge *edge, BMEdge *oedge,
                                         const SubDParams *params, float percent,
                                         float percent2,
                                         BMEdge **out, BMVert *vsta, BMVert *vend)
{
	BMVert *ev;
	
	ev = BM_edge_split(bm, edge, edge->v1, out, percent);

	BMO_elem_flag_enable(bm, ev, ELE_INNER);

	/* offset for smooth or sphere or fractal */
	alter_co(ev, oedge, params, percent2, vsta, vend);

#if 0 //BMESH_TODO
	/* clip if needed by mirror modifier */
	if (edge->v1->f2) {
		if (edge->v1->f2 & edge->v2->f2 & 1) {
			co[0] = 0.0f;
		}
		if (edge->v1->f2 & edge->v2->f2 & 2) {
			co[1] = 0.0f;
		}
		if (edge->v1->f2 & edge->v2->f2 & 4) {
			co[2] = 0.0f;
		}
	}
#endif
	
	interp_v3_v3v3(ev->no, vsta->no, vend->no, percent2);
	normalize_v3(ev->no);

	return ev;
}
void bmo_create_dimension_exec(BMesh *bm, BMOperator *op)
{
	BMOIter siter;
	BMVert *v1,*v2;
	BMDim *d;

	v1 = BMO_iter_new(&siter, op->slots_in, "verts", BM_VERT);
	v2 = BMO_iter_step(&siter);

	if (v1 && v2) {
		d = BM_dim_create(bm, v1, v2, NULL, BM_CREATE_NOP);

		BMO_elem_flag_enable(bm, d, EXT_KEEP);
		BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "dim.out", BM_DIM, EXT_KEEP);

	}
}
/* results in new vertex with correct coordinate, vertex normal and weight group info */
static BMVert *bm_subdivide_edge_addvert(
        BMesh *bm, BMEdge *edge, BMEdge *e_orig,
        const SubDParams *params,
        const float factor_edge_split, const float factor_subd,
        BMVert *v_a, BMVert *v_b,
        BMEdge **r_edge)
{
	BMVert *v_new;
	
	v_new = BM_edge_split(bm, edge, edge->v1, r_edge, factor_edge_split);

	BMO_elem_flag_enable(bm, v_new, ELE_INNER);

	/* offset for smooth or sphere or fractal */
	alter_co(v_new, e_orig, params, factor_subd, v_a, v_b);

#if 0 //BMESH_TODO
	/* clip if needed by mirror modifier */
	if (edge->v1->f2) {
		if (edge->v1->f2 & edge->v2->f2 & 1) {
			co[0] = 0.0f;
		}
		if (edge->v1->f2 & edge->v2->f2 & 2) {
			co[1] = 0.0f;
		}
		if (edge->v1->f2 & edge->v2->f2 & 4) {
			co[2] = 0.0f;
		}
	}
#endif
	
	interp_v3_v3v3(v_new->no, v_a->no, v_b->no, factor_subd);
	normalize_v3(v_new->no);

	return v_new;
}
示例#5
0
/**
 * <pre>
 *         v5
 *        / \
 *   s v6/---\ v4 s
 *      / \ / \
 *  sv7/---v---\ v3 s
 *    /  \/  \/ \
 *   v8--v0--v1--v2
 *      s    s
 * </pre>
 */
static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
                                const SubDParams *params)
{
	BMFace *f_new;
	BMEdge *e, *e_new, e_tmp;
	BMVert ***lines, *v, v1_tmp, v2_tmp;
	void *stackarr[1];
	int i, j, a, b, numcuts = params->numcuts;
	
	/* number of verts in each lin */
	lines = MEM_callocN(sizeof(void *) * (numcuts + 2), "triangle vert table");
	
	lines[0] = (BMVert **) stackarr;
	lines[0][0] = verts[numcuts * 2 + 1];
	
	lines[numcuts + 1] = MEM_callocN(sizeof(void *) * (numcuts + 2), "triangle vert table 2");
	for (i = 0; i < numcuts; i++) {
		lines[numcuts + 1][i + 1] = verts[i];
	}
	lines[numcuts + 1][0] = verts[numcuts * 3 + 2];
	lines[numcuts + 1][numcuts + 1] = verts[numcuts];

	for (i = 0; i < numcuts; i++) {
		lines[i + 1] = MEM_callocN(sizeof(void *) * (2 + i), "triangle vert table row");
		a = numcuts * 2 + 2 + i;
		b = numcuts + numcuts - i;
		e = connect_smallest_face(bm, verts[a], verts[b], &f_new);
		if (!e) goto cleanup;

		BMO_elem_flag_enable(bm, e, ELE_INNER);
		BMO_elem_flag_enable(bm, f_new, ELE_INNER);

		lines[i + 1][0] = verts[a];
		lines[i + 1][i + 1] = verts[b];
		
		e_tmp = *e;
		v1_tmp = *verts[a];
		v2_tmp = *verts[b];
		e_tmp.v1 = &v1_tmp;
		e_tmp.v2 = &v2_tmp;
		for (j = 0; j < i; j++) {
			v = subdivideedgenum(bm, e, &e_tmp, j, i, params, &e_new,
			                     verts[a], verts[b]);
			lines[i + 1][j + 1] = v;

			BMO_elem_flag_enable(bm, e_new, ELE_INNER);
		}
	}
	
	/**
	 * <pre>
	 *         v5
	 *        / \
	 *   s v6/---\ v4 s
	 *      / \ / \
	 *  sv7/---v---\ v3 s
	 *    /  \/  \/ \
	 *   v8--v0--v1--v2
	 *      s    s
	 * </pre>
	 */
	for (i = 1; i <= numcuts; i++) {
		for (j = 0; j < i; j++) {
			e = connect_smallest_face(bm, lines[i][j], lines[i + 1][j + 1], &f_new);

			BMO_elem_flag_enable(bm, e, ELE_INNER);
			BMO_elem_flag_enable(bm, f_new, ELE_INNER);

			e = connect_smallest_face(bm, lines[i][j + 1], lines[i + 1][j + 1], &f_new);

			BMO_elem_flag_enable(bm, e, ELE_INNER);
			BMO_elem_flag_enable(bm, f_new, ELE_INNER);
		}
	}

cleanup:
	for (i = 1; i < numcuts + 2; i++) {
		if (lines[i]) MEM_freeN(lines[i]);
	}

	MEM_freeN(lines);
}
示例#6
0
/**
 * <pre>
 *            v8--v7-v6--v5
 *            |     s    |
 *            |v9 s     s|v4
 * first line |          |   last line
 *            |v10s s   s|v3
 *            v11-v0--v1-v2
 *
 *            it goes from bottom up
 * </pre>
 */
static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
                                 const SubDParams *params)
{
	BMFace *f_new;
	BMVert *v, *v1, *v2;
	BMEdge *e, *e_new, e_tmp;
	BMVert **lines;
	int numcuts = params->numcuts;
	int i, j, a, b, s = numcuts + 2 /* , totv = numcuts * 4 + 4 */;

	lines = MEM_callocN(sizeof(BMVert *) * (numcuts + 2) * (numcuts + 2), "q_4edge_split");
	/* build a 2-dimensional array of verts,
	 * containing every vert (and all new ones)
	 * in the face */

	/* first line */
	for (i = 0; i < numcuts + 2; i++) {
		lines[i] = verts[numcuts * 3 + 2 + (numcuts - i + 1)];
	}

	/* last line */
	for (i = 0; i < numcuts + 2; i++) {
		lines[(s - 1) * s + i] = verts[numcuts + i];
	}
	
	/* first and last members of middle lines */
	for (i = 0; i < numcuts; i++) {
		a = i;
		b = numcuts + 1 + numcuts + 1 + (numcuts - i - 1);
		
		e = connect_smallest_face(bm, verts[a], verts[b], &f_new);
		if (!e)
			continue;

		BMO_elem_flag_enable(bm, e, ELE_INNER);
		BMO_elem_flag_enable(bm, f_new, ELE_INNER);

		
		v1 = lines[(i + 1) * s] = verts[a];
		v2 = lines[(i + 1) * s + s - 1] = verts[b];
		
		e_tmp = *e;
		for (a = 0; a < numcuts; a++) {
			v = subdivideedgenum(bm, e, &e_tmp, a, numcuts, params, &e_new,
			                     v1, v2);

			BMESH_ASSERT(v != NULL);

			BMO_elem_flag_enable(bm, e_new, ELE_INNER);
			lines[(i + 1) * s + a + 1] = v;
		}
	}

	for (i = 1; i < numcuts + 2; i++) {
		for (j = 1; j <= numcuts; j++) {
			a = i * s + j;
			b = (i - 1) * s + j;
			e = connect_smallest_face(bm, lines[a], lines[b], &f_new);
			if (!e)
				continue;

			BMO_elem_flag_enable(bm, e, ELE_INNER);
			BMO_elem_flag_enable(bm, f_new, ELE_INNER);
		}
	}

	MEM_freeN(lines);
}