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!
This commit is contained in:
Campbell Barton 2017-01-19 09:04:50 +11:00
parent fd4728c85a
commit 11187e8628
1 changed files with 26 additions and 7 deletions

View File

@ -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);
}