diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-12-24 04:04:03 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-12-24 04:13:58 +0400 |
commit | 04a902965e5e226e69c5c6e912dd2f513448d2ac (patch) | |
tree | c65a2c9613f5a336f6c2739b5dabc5fbad348230 /source/blender/bmesh/operators | |
parent | d94db03ac8ef9f6a10e42f01d622421fe3f216bb (diff) |
BMesh optimize face splitting by taking loops rather then verts
- add BM_vert_pair_share_face
- add BM_loop_is_adjacent
- remove BM_verts_connect
Diffstat (limited to 'source/blender/bmesh/operators')
-rw-r--r-- | source/blender/bmesh/operators/bmo_connect.c | 14 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_connect_nonplanar.c | 17 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_dissolve.c | 2 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_removedoubles.c | 32 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_subdivide.c | 25 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_subdivide_edgering.c | 2 |
6 files changed, 49 insertions, 43 deletions
diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c index d0f64eb2892..3d2c8c3d020 100644 --- a/source/blender/bmesh/operators/bmo_connect.c +++ b/source/blender/bmesh/operators/bmo_connect.c @@ -63,7 +63,7 @@ static int bm_face_connect_verts(BMesh *bm, BMFace *f) continue; } - if (l_last != l->prev && l_last != l->next) { + if (!BM_loop_is_adjacent(l_last, l)) { BMLoop **l_pair = STACK_PUSH_RET(loops_split); l_pair[0] = l_last; l_pair[1] = l; @@ -96,7 +96,17 @@ static int bm_face_connect_verts(BMesh *bm, BMFace *f) } for (i = 0; i < STACK_SIZE(verts_pair); i++) { - f_new = BM_face_split(bm, f, verts_pair[i][0], verts_pair[i][1], &l_new, NULL, false); + BMLoop *l_a, *l_b; + + if ((l_a = BM_face_vert_share_loop(f, verts_pair[i][0])) && + (l_b = BM_face_vert_share_loop(f, verts_pair[i][1]))) + { + f_new = BM_face_split(bm, f, l_a, l_b, &l_new, NULL, false); + } + else { + f_new = NULL; + } + f = f_new; if (!l_new || !f_new) { diff --git a/source/blender/bmesh/operators/bmo_connect_nonplanar.c b/source/blender/bmesh/operators/bmo_connect_nonplanar.c index bd7a625406c..334647fc68c 100644 --- a/source/blender/bmesh/operators/bmo_connect_nonplanar.c +++ b/source/blender/bmesh/operators/bmo_connect_nonplanar.c @@ -86,7 +86,7 @@ static float bm_face_subset_calc_planar(BMLoop *l_first, BMLoop *l_last, const f return delta_z; } -static bool bm_face_split_find(BMFace *f, BMVert *v_pair[2], float *r_angle) +static bool bm_face_split_find(BMFace *f, BMLoop *l_pair[2], float *r_angle) { BMLoop *l_iter, *l_first; BMLoop **l_arr = BLI_array_alloca(l_arr, f->len); @@ -111,9 +111,7 @@ static bool bm_face_split_find(BMFace *f, BMVert *v_pair[2], float *r_angle) BMLoop *l_b = l_arr[i_b]; /* check these are not touching * (we could be smarter here) */ - if ((l_a->next != l_b) && - (l_a->prev != l_b)) - { + if (!BM_loop_is_adjacent(l_a, l_b)) { /* first calculate normals */ float no_a[3], no_b[3]; @@ -130,8 +128,8 @@ static bool bm_face_split_find(BMFace *f, BMVert *v_pair[2], float *r_angle) BM_face_legal_splits(f, &l_split, 1); if (l_split[0]) { err_best = err_test; - v_pair[0] = l_a->v; - v_pair[1] = l_b->v; + l_pair[0] = l_a; + l_pair[1] = l_b; angle_best = angle_normalized_v3v3(no_a, no_b); found = true; @@ -151,13 +149,14 @@ static bool bm_face_split_find(BMFace *f, BMVert *v_pair[2], float *r_angle) static bool bm_face_split_by_angle(BMesh *bm, BMFace *f, BMFace *r_f_pair[2], const float angle_limit) { - BMVert *v_pair[2]; + BMLoop *l_pair[2]; float angle; - if (bm_face_split_find(f, v_pair, &angle) && (angle > angle_limit)) { + if (bm_face_split_find(f, l_pair, &angle) && (angle > angle_limit)) { BMFace *f_new; BMLoop *l_new; - f_new = BM_face_split(bm, f, v_pair[0], v_pair[1], &l_new, NULL, false); + + f_new = BM_face_split(bm, f, l_pair[0], l_pair[1], &l_new, NULL, false); if (f_new) { r_f_pair[0] = f; r_f_pair[1] = f_new; diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c index ae645b97874..60b96e35057 100644 --- a/source/blender/bmesh/operators/bmo_dissolve.c +++ b/source/blender/bmesh/operators/bmo_dissolve.c @@ -99,7 +99,7 @@ static void bm_face_split(BMesh *bm, const short oflag) if (BMO_elem_flag_test(bm, l->next->v, oflag) == 0 && BMO_elem_flag_test(bm, l->prev->v, oflag) == 0) { - BM_face_split(bm, l->f, l->next->v, l->prev->v, NULL, NULL, true); + BM_face_split(bm, l->f, l->next, l->prev, NULL, NULL, true); } } } diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c index cc5a635092a..8eb94b9a743 100644 --- a/source/blender/bmesh/operators/bmo_removedoubles.c +++ b/source/blender/bmesh/operators/bmo_removedoubles.c @@ -40,30 +40,32 @@ static void remdoubles_splitface(BMFace *f, BMesh *bm, BMOperator *op, BMOpSlot *slot_targetmap) { BMIter liter; - BMLoop *l; - BMVert *v2, *v_double; + BMLoop *l, *l_tar, *l_double; bool split = false; BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - v2 = BMO_slot_map_elem_get(slot_targetmap, l->v); - /* ok: if v2 is NULL (e.g. not in the map) then it's + BMVert *v_tar = BMO_slot_map_elem_get(slot_targetmap, l->v); + /* ok: if v_tar is NULL (e.g. not in the map) then it's * a target vert, otherwise it's a double */ - if ((v2 && BM_vert_in_face(f, v2)) && - (v2 != l->prev->v) && - (v2 != l->next->v)) - { - v_double = l->v; - split = true; - break; + if (v_tar) { + BMLoop *l_tar = BM_face_vert_share_loop(f, v_tar); + + if (l_tar && (l_tar != l) && !BM_loop_is_adjacent(l_tar, l)) { + l_double = l; + split = true; + break; + } } } - if (split && v_double != v2) { + if (split) { BMLoop *l_new; - BMFace *f2 = BM_face_split(bm, f, v_double, v2, &l_new, NULL, false); + BMFace *f_new; - remdoubles_splitface(f, bm, op, slot_targetmap); - remdoubles_splitface(f2, bm, op, slot_targetmap); + f_new = BM_face_split(bm, f, l_double, l_tar, &l_new, NULL, false); + + remdoubles_splitface(f, bm, op, slot_targetmap); + remdoubles_splitface(f_new, bm, op, slot_targetmap); } } diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index b3b9cecf389..723595771a1 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -133,28 +133,23 @@ typedef struct SubDPattern { /* 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) +static BMEdge *connect_smallest_face(BMesh *bm, BMVert *v_a, BMVert *v_b, BMFace **r_f_new) { - BMIter iter, iter2; - BMVert *v; BMLoop *l_new; - BMFace *f, *f_cur = NULL; + 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. */ - 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; - } - } - } + f = BM_vert_pair_share_face(v_a, v_b, &l_a, &l_b); + + if (f) { + BMFace *f_new; - if (f_cur) { - f = BM_face_split(bm, f_cur, v1, v2, &l_new, NULL, false); + f_new = BM_face_split(bm, f, l_a, l_b, &l_new, NULL, false); - if (r_f_new) *r_f_new = f; + if (r_f_new) *r_f_new = f_new; return l_new ? l_new->e : NULL; } @@ -1118,7 +1113,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op) if (loops_split[j][0]) { BMFace *f_new; BLI_assert(BM_edge_exists(loops_split[j][0]->v, loops_split[j][1]->v) == NULL); - f_new = BM_face_split(bm, face, loops_split[j][0]->v, loops_split[j][1]->v, &l_new, NULL, false); + f_new = BM_face_split(bm, face, loops_split[j][0], loops_split[j][1], &l_new, NULL, false); if (f_new) { BMO_elem_flag_enable(bm, l_new->e, ELE_INNER); } diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c index d1ec06c5486..182bf0518ef 100644 --- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c +++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c @@ -828,7 +828,7 @@ static void bm_face_slice(BMesh *bm, BMLoop *l, const int cuts) for (i = 0; i < cuts; i++) { /* no chance of double */ - BM_face_split(bm, l_new->f, l_new->prev->v, l_new->next->next->v, &l_new, NULL, false); + BM_face_split(bm, l_new->f, l_new->prev, l_new->next->next, &l_new, NULL, false); if (l_new->f->len < l_new->radial_next->f->len) { l_new = l_new->radial_next; } |