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); }
/* 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; }
/** * <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); }
/** * <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); }