From bed5ae53660f742546db3467b31f8f390c59942b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 15 Mar 2012 23:23:04 +0000 Subject: *picky* fix for edge rotate - Edge rotate would leave verts selected, this would give problems because those selections would leave edges that would try to rotate when run again. now de-select old verts on edge rotate. - Rotating into hidden verts gave odd results, now make sure hidden state is ok. - BMO_slot_buffer_hflag_disable / BMO_slot_buffer_hflag_enable now have flushing for the hide flag too. --- source/blender/bmesh/bmesh_operator_api.h | 4 +-- source/blender/bmesh/intern/bmesh_mods.c | 19 ++++++++++-- source/blender/bmesh/intern/bmesh_operators.c | 42 +++++++++++++++------------ source/blender/editors/mesh/bmesh_tools.c | 7 +++++ 4 files changed, 49 insertions(+), 23 deletions(-) (limited to 'source') diff --git a/source/blender/bmesh/bmesh_operator_api.h b/source/blender/bmesh/bmesh_operator_api.h index beb601878c8..d45092e1d88 100644 --- a/source/blender/bmesh/bmesh_operator_api.h +++ b/source/blender/bmesh/bmesh_operator_api.h @@ -303,10 +303,10 @@ void BMO_slot_buffer_flag_disable(BMesh *bm, BMOperator *op, const char *slotnam /* tool-flags all elements inside an element slot array with flag flag. */ void BMO_slot_buffer_hflag_enable(BMesh *bm, BMOperator *op, const char *slotname, - const char hflag, const char htype, char do_flush_select); + const char hflag, const char htype, const char do_flush); /* clears tool-flag flag from all elements inside a slot array. */ void BMO_slot_buffer_hflag_disable(BMesh *bm, BMOperator *op, const char *slotname, - const char hflag, const char htype, char do_flush_select); + const char hflag, const char htype, const char do_flush); /* puts every element of type type (which is a bitmask) with header flag * flag, into a slot. note: ignores hidden elements (e.g. elements with diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index 72f6814dc89..5248276bae6 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -824,7 +824,7 @@ void BM_edge_rotate_calc(BMesh *bm, BMEdge *e, int ccw, BM_edge_ordered_verts(e, &v1, &v2); /* we could swap the verts _or_ the faces, swapping faces - * gives more pradictable resuts since that way the next vert + * gives more predictable resuts since that way the next vert * just sitches from face fa / fb */ if (ccw) { SWAP(BMFace *, fa, fb); @@ -1006,6 +1006,8 @@ BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const short ccw, const short check_ BMLoop *l1, *l2; BMFace *f; BMEdge *e_new = NULL; + char f_hflag_prev_1; + char f_hflag_prev_2; if (!BM_edge_rotate_check(bm, e)) { return NULL; @@ -1017,8 +1019,6 @@ BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const short ccw, const short check_ v1 = l1->v; v2 = l2->v; - - /* --------------------------------------- */ /* Checking Code - make sure we can rotate */ @@ -1053,6 +1053,9 @@ BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const short ccw, const short check_ * if splice if disabled, always add in a new edge even if theres one there. */ e_new = BM_edge_create(bm, v1, v2, e, (check_flag & BM_EDGEROT_CHECK_SPLICE)!=0); + f_hflag_prev_1 = l1->f->head.hflag; + f_hflag_prev_2 = l2->f->head.hflag; + /* don't delete the edge, manually remove the egde after so we can copy its attributes */ f = BM_faces_join_pair(bm, l1->f, l2->f, NULL); @@ -1066,6 +1069,16 @@ BMEdge *BM_edge_rotate(BMesh *bm, BMEdge *e, const short ccw, const short check_ if (!BM_face_split(bm, f, v1, v2, NULL, NULL, TRUE)) { return NULL; } + else { + /* we should reallty be able to know the faces some other way, + * rather then fetching them back from the edge, but this is predictable + * where using the return values from face split isnt. - campbell */ + BMFace *fa, *fb; + if (BM_edge_face_pair(e_new, &fa, &fb)) { + fa->head.hflag = f_hflag_prev_1; + fb->head.hflag = f_hflag_prev_2; + } + } return e_new; } diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index eb83d5f6b35..0d0dc226a24 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -785,26 +785,29 @@ void BMO_slot_buffer_from_flag(BMesh *bm, BMOperator *op, const char *slotname, * using the selection API where appropriate. */ void BMO_slot_buffer_hflag_enable(BMesh *bm, BMOperator *op, const char *slotname, - const char hflag, const char htype, char do_flush_select) + const char hflag, const char htype, const char do_flush) { BMOpSlot *slot = BMO_slot_get(op, slotname); BMElem **data = slot->data.p; int i; + const char do_flush_select = (do_flush && (hflag & BM_ELEM_SELECT)); + const char do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN)); BLI_assert(slot->slottype == BMO_OP_SLOT_ELEMENT_BUF); - if (!(hflag & BM_ELEM_SELECT)) { - do_flush_select = FALSE; - } - - for (i = 0; i < slot->len; i++) { - if (!(htype & data[i]->head.htype)) + for (i = 0; i < slot->len; i++, data++) { + if (!(htype & (*data)->head.htype)) continue; if (do_flush_select) { - BM_elem_select_set(bm, data[i], TRUE); + BM_elem_select_set(bm, *data, TRUE); } - BM_elem_flag_enable(data[i], hflag); + + if (do_flush_hide) { + BM_elem_hide_set(bm, *data, FALSE); + } + + BM_elem_flag_enable(*data, hflag); } } @@ -815,29 +818,32 @@ void BMO_slot_buffer_hflag_enable(BMesh *bm, BMOperator *op, const char *slotnam * using the selection API where appropriate. */ void BMO_slot_buffer_hflag_disable(BMesh *bm, BMOperator *op, const char *slotname, - const char hflag, const char htype, char do_flush_select) + const char hflag, const char htype, const char do_flush) { BMOpSlot *slot = BMO_slot_get(op, slotname); BMElem **data = slot->data.p; int i; + const char do_flush_select = (do_flush && (hflag & BM_ELEM_SELECT)); + const char do_flush_hide = (do_flush && (hflag & BM_ELEM_HIDDEN)); BLI_assert(slot->slottype == BMO_OP_SLOT_ELEMENT_BUF); - if (!(hflag & BM_ELEM_SELECT)) { - do_flush_select = FALSE; - } - - for (i = 0; i < slot->len; i++) { - if (!(htype & data[i]->head.htype)) + for (i = 0; i < slot->len; i++, data++) { + if (!(htype & (*data)->head.htype)) continue; if (do_flush_select) { - BM_elem_select_set(bm, data[i], FALSE); + BM_elem_select_set(bm, *data, FALSE); } - BM_elem_flag_disable(data[i], hflag); + if (do_flush_hide) { + BM_elem_hide_set(bm, *data, FALSE); + } + + BM_elem_flag_disable(*data, hflag); } } + int BMO_vert_edge_flags_count(BMesh *bm, BMVert *v, const short oflag) { int count = 0; diff --git a/source/blender/editors/mesh/bmesh_tools.c b/source/blender/editors/mesh/bmesh_tools.c index 13852667d35..3a62bcb3b79 100644 --- a/source/blender/editors/mesh/bmesh_tools.c +++ b/source/blender/editors/mesh/bmesh_tools.c @@ -1380,8 +1380,15 @@ static int edge_rotate_selected(bContext *C, wmOperator *op) EDBM_InitOpf(em, &bmop, op, "edgerotate edges=%he ccw=%b", BM_ELEM_TAG, do_ccw); + /* avoids leaving old verts selected which can be a problem running multiple times, + * since this means the edges become selected around the face which then attempt to rotate */ + BMO_slot_buffer_hflag_disable(em->bm, &bmop, "edges", BM_ELEM_SELECT, BM_EDGE, TRUE); + BMO_op_exec(em->bm, &bmop); + /* edges may rotate into hidden vertices, if this does _not_ run we get an ilogical state */ + BMO_slot_buffer_hflag_disable(em->bm, &bmop, "edgeout", BM_ELEM_HIDDEN, BM_EDGE, TRUE); BMO_slot_buffer_hflag_enable(em->bm, &bmop, "edgeout", BM_ELEM_SELECT, BM_EDGE, TRUE); + EDBM_selectmode_flush(em); if (!EDBM_FinishOp(em, &bmop, op, TRUE)) { return OPERATOR_CANCELLED; -- cgit v1.2.3