From 11187e86283a2bada088f718dd6012e0c7d6d19e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 19 Jan 2017 09:04:50 +1100 Subject: Fix face-creation with existing hidden geometry - face-create-extend option could add hidden verts and edges into the selection history (invalid state). - faces could be created that included existing hidden edges that remained hidden (invalid state too). - newly created faces could copy hidden flag from surrounding faces, giving very confusing results (looks as if face creation failed). Surprising nobody noticed these years old bugs! --- source/blender/editors/mesh/editmesh_tools.c | 33 ++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'source') diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index c57b0215d46..8f004bcf72b 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -684,27 +684,38 @@ static void edbm_add_edge_face_exec__tricky_finalize_sel(BMesh *bm, BMElem *ele_ /* now we need to find the edge that isnt connected to this element */ BM_select_history_clear(bm); + /* Notes on hidden geometry: + * - un-hide the face since its possible hidden was copied when copying surrounding face attributes. + * - un-hide before adding to select history + * since we may extend into an existing, hidden vert/edge. + */ + + BM_elem_flag_disable(f, BM_ELEM_HIDDEN); + BM_face_select_set(bm, f, false); + if (ele_desel->head.htype == BM_VERT) { BMLoop *l = BM_face_vert_share_loop(f, (BMVert *)ele_desel); BLI_assert(f->len == 3); - BM_face_select_set(bm, f, false); BM_vert_select_set(bm, (BMVert *)ele_desel, false); - BM_edge_select_set(bm, l->next->e, true); BM_select_history_store(bm, l->next->e); } else { BMLoop *l = BM_face_edge_share_loop(f, (BMEdge *)ele_desel); BLI_assert(f->len == 4 || f->len == 3); - BM_face_select_set(bm, f, false); + BM_edge_select_set(bm, (BMEdge *)ele_desel, false); if (f->len == 4) { - BM_edge_select_set(bm, l->next->next->e, true); - BM_select_history_store(bm, l->next->next->e); + BMEdge *e_active = l->next->next->e; + BM_elem_flag_disable(e_active, BM_ELEM_HIDDEN); + BM_edge_select_set(bm, e_active, true); + BM_select_history_store(bm, e_active); } else { - BM_vert_select_set(bm, l->next->next->v, true); - BM_select_history_store(bm, l->next->next->v); + BMVert *v_active = l->next->next->v; + BM_elem_flag_disable(v_active, BM_ELEM_HIDDEN); + BM_vert_select_set(bm, v_active, true); + BM_select_history_store(bm, v_active); } } } @@ -758,6 +769,14 @@ static int edbm_add_edge_face_exec(bContext *C, wmOperator *op) else #endif { + /* Newly created faces may include existing hidden edges, + * copying face data from surrounding, may have copied hidden face flag too. + * + * Important that faces use flushing since 'edges.out' wont include hidden edges that already existed. + */ + BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_HIDDEN, true); + BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_HIDDEN, false); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "edges.out", BM_EDGE, BM_ELEM_SELECT, true); } -- cgit v1.2.3