diff options
Diffstat (limited to 'source/blender/bmesh/operators')
-rw-r--r-- | source/blender/bmesh/operators/bmo_bevel.c | 4 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_dupe.c | 73 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_extrude.c | 20 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_subdivide.c | 39 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_subdivide_edgering.c | 6 |
5 files changed, 103 insertions, 39 deletions
diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c index 2ae87b64286..9247c64d3fb 100644 --- a/source/blender/bmesh/operators/bmo_bevel.c +++ b/source/blender/bmesh/operators/bmo_bevel.c @@ -63,7 +63,9 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) } } - BM_mesh_bevel(bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, loop_slide); + BM_mesh_bevel( + bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, + loop_slide); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG); BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_TAG); diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c index eed87ed20af..c50c7657deb 100644 --- a/source/blender/bmesh/operators/bmo_dupe.c +++ b/source/blender/bmesh/operators/bmo_dupe.c @@ -26,6 +26,8 @@ * Duplicate, Split, Split operators. */ +#include "MEM_guardedalloc.h" + #include "BLI_math.h" #include "BLI_alloca.h" @@ -486,9 +488,29 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op) steps = BMO_slot_int_get(op->slots_in, "steps"); phi = BMO_slot_float_get(op->slots_in, "angle") / steps; do_dupli = BMO_slot_bool_get(op->slots_in, "use_duplicate"); + const bool use_normal_flip = BMO_slot_bool_get(op->slots_in, "use_normal_flip"); + /* Caller needs to perform other sanity checks (such as the spin being 360d). */ + const bool use_merge = BMO_slot_bool_get(op->slots_in, "use_merge") && steps >= 3; axis_angle_normalized_to_mat3(rmat, axis, phi); + BMVert **vtable = NULL; + if (use_merge) { + vtable = MEM_mallocN(sizeof(BMVert *) * bm->totvert, __func__); + int i = 0; + BMIter iter; + BMVert *v; + BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) { + vtable[i] = v; + /* Evil! store original index in normal, + * this is duplicated into every other vertex. + * So we can read the original from the final. + * + * The normals must be recalculated anyway. */ + *((int *)&v->no[0]) = i; + } + } + BMO_slot_copy(op, slots_in, "geom", op, slots_out, "geom_last.out"); for (a = 0; a < steps; a++) { @@ -503,14 +525,47 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op) BMO_op_finish(bm, &dupop); } else { - BMO_op_initf(bm, &extop, op->flag, "extrude_face_region geom=%S", - op, "geom_last.out"); + BMO_op_initf(bm, &extop, op->flag, "extrude_face_region geom=%S use_normal_flip=%b", + op, "geom_last.out", use_normal_flip && (a == 0)); BMO_op_exec(bm, &extop); - BMO_op_callf(bm, op->flag, - "rotate cent=%v matrix=%m3 space=%s verts=%S", - cent, rmat, op, "space", &extop, "geom.out"); - BMO_slot_copy(&extop, slots_out, "geom.out", - op, slots_out, "geom_last.out"); + if ((use_merge && (a == steps - 1)) == false) { + BMO_op_callf(bm, op->flag, + "rotate cent=%v matrix=%m3 space=%s verts=%S", + cent, rmat, op, "space", &extop, "geom.out"); + BMO_slot_copy(&extop, slots_out, "geom.out", + op, slots_out, "geom_last.out"); + } + else { + /* Merge first/last vertices and edges (maintaining 'geom.out' state). */ + BMOpSlot *slot_geom_out = BMO_slot_get(extop.slots_out, "geom.out"); + BMElem **elem_array = (BMElem **)slot_geom_out->data.buf; + int elem_array_len = slot_geom_out->len; + for (int i = 0; i < elem_array_len; ) { + if (elem_array[i]->head.htype == BM_VERT) { + BMVert *v_src = (BMVert *)elem_array[i]; + BMVert *v_dst = vtable[*((const int *)&v_src->no[0])]; + BM_vert_splice(bm, v_dst, v_src); + elem_array_len--; + elem_array[i] = elem_array[elem_array_len]; + } + else { + i++; + } + } + for (int i = 0; i < elem_array_len; ) { + if (elem_array[i]->head.htype == BM_EDGE) { + BMEdge *e_src = (BMEdge *)elem_array[i]; + BMEdge *e_dst = BM_edge_find_double(e_src); + BM_edge_splice(bm, e_dst, e_src); + elem_array_len--; + elem_array[i] = elem_array[elem_array_len]; + } + else { + i++; + } + } + slot_geom_out->len = elem_array_len; + } BMO_op_finish(bm, &extop); } @@ -521,4 +576,8 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op) dvec, op, "space", op, "geom_last.out"); } } + + if (vtable) { + MEM_freeN(vtable); + } } diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c index 3a6fbd419c1..8c1624740da 100644 --- a/source/blender/bmesh/operators/bmo_extrude.c +++ b/source/blender/bmesh/operators/bmo_extrude.c @@ -186,6 +186,7 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op) BMOperator dupeop; BMFace *f; BMEdge *e, *e_new; + const bool use_normal_flip = BMO_slot_bool_get(op->slots_in, "use_normal_flip"); BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) { BMO_edge_flag_enable(bm, e, EXT_INPUT); @@ -212,7 +213,9 @@ void bmo_extrude_edge_only_exec(BMesh *bm, BMOperator *op) BMVert *f_verts[4]; e_new = BMO_iter_map_value_ptr(&siter); - if (e->l && e->v1 != e->l->v) { + + const bool edge_normal_flip = !(e->l && e->v1 != e->l->v); + if (edge_normal_flip == use_normal_flip) { f_verts[0] = e->v1; f_verts[1] = e->v2; f_verts[2] = e_new->v2; @@ -332,9 +335,10 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) BMEdge *e, *e_new; BMVert *v; BMFace *f; - bool found, fwd, delorig = false; + bool found, delorig = false; BMOpSlot *slot_facemap_out; BMOpSlot *slot_edges_exclude; + const bool use_normal_flip = BMO_slot_bool_get(op->slots_in, "use_normal_flip"); /* initialize our sub-operators */ BMO_op_initf( @@ -488,13 +492,11 @@ void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op) /* orient loop to give same normal as a loop of newedge * if it exists (will be an extruded face), * else same normal as a loop of e, if it exists */ - if (!e_new->l) - fwd = !e->l || !(e->l->v == e->v1); - else - fwd = (e_new->l->v == e_new->v1); - - - if (fwd) { + const bool edge_normal_flip = !( + e_new->l ? + (e_new->l->v == e_new->v1) : + (!e->l || !(e->l->v == e->v1))); + if (edge_normal_flip == use_normal_flip) { f_verts[0] = e->v1; f_verts[1] = e->v2; f_verts[2] = e_new->v2; diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index c8ba2134a73..66730f8c837 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -182,15 +182,12 @@ static void interp_slerp_co_no_v3( /* calculate sphere 'center' */ { /* use point on plane to */ - float plane_a[4], plane_b[4], plane_c[4]; float no_mid[3], no_ortho[3]; /* pass this as an arg instead */ #if 0 float no_dir[3]; #endif - float v_a_no_ortho[3], v_b_no_ortho[3]; - add_v3_v3v3(no_mid, no_a, no_b); normalize_v3(no_mid); @@ -200,24 +197,28 @@ static void interp_slerp_co_no_v3( #endif /* axis of slerp */ + bool center_ok = false; cross_v3_v3v3(no_ortho, no_mid, no_dir); - normalize_v3(no_ortho); - - /* create planes */ - cross_v3_v3v3(v_a_no_ortho, no_ortho, no_a); - cross_v3_v3v3(v_b_no_ortho, no_ortho, no_b); - project_v3_plane(v_a_no_ortho, no_ortho, v_a_no_ortho); - project_v3_plane(v_b_no_ortho, no_ortho, v_b_no_ortho); - - plane_from_point_normal_v3(plane_a, co_a, v_a_no_ortho); - plane_from_point_normal_v3(plane_b, co_b, v_b_no_ortho); - plane_from_point_normal_v3(plane_c, co_b, no_ortho); - - /* find the sphere center from 3 planes */ - if (isect_plane_plane_plane_v3(plane_a, plane_b, plane_c, center)) { - /* pass */ + if (normalize_v3(no_ortho) != 0.0f) { + float plane_a[4], plane_b[4], plane_c[4]; + float v_a_no_ortho[3], v_b_no_ortho[3]; + + /* create planes */ + cross_v3_v3v3(v_a_no_ortho, no_ortho, no_a); + cross_v3_v3v3(v_b_no_ortho, no_ortho, no_b); + project_v3_plane(v_a_no_ortho, no_ortho, v_a_no_ortho); + project_v3_plane(v_b_no_ortho, no_ortho, v_b_no_ortho); + + plane_from_point_normal_v3(plane_a, co_a, v_a_no_ortho); + plane_from_point_normal_v3(plane_b, co_b, v_b_no_ortho); + plane_from_point_normal_v3(plane_c, co_b, no_ortho); + + /* find the sphere center from 3 planes */ + if (isect_plane_plane_plane_v3(plane_a, plane_b, plane_c, center)) { + center_ok = true; + } } - else { + if (center_ok == false) { mid_v3_v3v3(center, co_a, co_b); } } diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c index e6881f6d8b1..251a79e8ff5 100644 --- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c +++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c @@ -505,7 +505,7 @@ static LoopPairStore *bm_edgering_pair_store_create( for (v_iter = lb->first, i = 0; v_iter; v_iter = v_iter->next, i++) { BMVert *v = v_iter->data; bm_vert_calc_surface_tangent(bm, v, nor[i]); - BLI_ghash_insert(nors_gh_iter, v, SET_UINT_IN_POINTER(i)); + BLI_ghash_insert(nors_gh_iter, v, POINTER_FROM_UINT(i)); } } @@ -768,8 +768,8 @@ static void bm_edgering_pair_interpolate( bm_vert_calc_surface_tangent(bm, v_b, no_b); #else { - const uint index_a = GET_UINT_FROM_POINTER(BLI_ghash_lookup(lpair->nors_gh_a, v_a)); - const uint index_b = GET_UINT_FROM_POINTER(BLI_ghash_lookup(lpair->nors_gh_b, v_b)); + const uint index_a = POINTER_AS_UINT(BLI_ghash_lookup(lpair->nors_gh_a, v_a)); + const uint index_b = POINTER_AS_UINT(BLI_ghash_lookup(lpair->nors_gh_b, v_b)); BLI_assert(BLI_ghash_haskey(lpair->nors_gh_a, v_a)); BLI_assert(BLI_ghash_haskey(lpair->nors_gh_b, v_b)); |