[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [52122] trunk/blender/source/blender: fix [#33142] Ctrl LMB higher selection mode in edit mode sometimes selects extra elements
Campbell Barton
ideasman42 at gmail.com
Mon Nov 12 00:34:02 CET 2012
Revision: 52122
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=52122
Author: campbellbarton
Date: 2012-11-11 23:33:59 +0000 (Sun, 11 Nov 2012)
Log Message:
-----------
fix [#33142] Ctrl LMB higher selection mode in edit mode sometimes selects extra elements
Modified Paths:
--------------
trunk/blender/source/blender/blenlib/intern/math_base_inline.c
trunk/blender/source/blender/bmesh/intern/bmesh_queries.c
trunk/blender/source/blender/bmesh/intern/bmesh_queries.h
trunk/blender/source/blender/editors/mesh/editmesh_select.c
trunk/blender/source/blender/editors/space_view3d/view3d_header.c
Modified: trunk/blender/source/blender/blenlib/intern/math_base_inline.c
===================================================================
--- trunk/blender/source/blender/blenlib/intern/math_base_inline.c 2012-11-11 23:04:59 UTC (rev 52121)
+++ trunk/blender/source/blender/blenlib/intern/math_base_inline.c 2012-11-11 23:33:59 UTC (rev 52122)
@@ -139,6 +139,25 @@
return n;
}
+MINLINE unsigned int highest_order_bit_i(unsigned int n)
+{
+ n |= (n >> 1);
+ n |= (n >> 2);
+ n |= (n >> 4);
+ n |= (n >> 8);
+ n |= (n >> 16);
+ return n - (n >> 1);
+}
+
+MINLINE unsigned short highest_order_bit_s(unsigned short n)
+{
+ n |= (n >> 1);
+ n |= (n >> 2);
+ n |= (n >> 4);
+ n |= (n >> 8);
+ return n - (n >> 1);
+}
+
MINLINE float min_ff(float a, float b)
{
return (a < b) ? a : b;
Modified: trunk/blender/source/blender/bmesh/intern/bmesh_queries.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_queries.c 2012-11-11 23:04:59 UTC (rev 52121)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_queries.c 2012-11-11 23:33:59 UTC (rev 52122)
@@ -1419,3 +1419,38 @@
return ok;
}
+
+/* convenience functiosn for checking flags */
+int BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag)
+{
+ return (BM_elem_flag_test(e->v1, hflag) ||
+ BM_elem_flag_test(e->v2, hflag));
+}
+
+int BM_face_is_any_vert_flag_test(BMFace *f, const char hflag)
+{
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (BM_elem_flag_test(l_iter->v, hflag)) {
+ return TRUE;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ return FALSE;
+}
+
+int BM_face_is_any_edge_flag_test(BMFace *f, const char hflag)
+{
+ BMLoop *l_iter;
+ BMLoop *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (BM_elem_flag_test(l_iter->e, hflag)) {
+ return TRUE;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ return FALSE;
+}
Modified: trunk/blender/source/blender/bmesh/intern/bmesh_queries.h
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_queries.h 2012-11-11 23:04:59 UTC (rev 52121)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_queries.h 2012-11-11 23:33:59 UTC (rev 52122)
@@ -100,4 +100,8 @@
void BM_edge_ordered_verts_ex(BMEdge *edge, BMVert **r_v1, BMVert **r_v2,
BMLoop *edge_loop);
+int BM_edge_is_any_vert_flag_test(BMEdge *e, const char hflag);
+int BM_face_is_any_vert_flag_test(BMFace *f, const char hflag);
+int BM_face_is_any_edge_flag_test(BMFace *f, const char hflag);
+
#endif /* __BMESH_QUERIES_H__ */
Modified: trunk/blender/source/blender/editors/mesh/editmesh_select.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_select.c 2012-11-11 23:04:59 UTC (rev 52121)
+++ trunk/blender/source/blender/editors/mesh/editmesh_select.c 2012-11-11 23:33:59 UTC (rev 52122)
@@ -1881,50 +1881,45 @@
BMFace *efa;
BMIter iter;
+ /* first tag-to-select, then select --- this avoids a feedback loop */
+
/* have to find out what the selectionmode was previously */
if (selectmode_old == SCE_SELECT_VERTEX) {
if (selectmode_new == SCE_SELECT_EDGE) {
- /* select all edges associated with every selected vertex */
- eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL);
- for (; eed; eed = BM_iter_step(&iter)) {
- if ((BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) ||
- BM_elem_flag_test(eed->v2, BM_ELEM_SELECT)))
- {
+ /* select all edges associated with every selected vert */
+ BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
+ BM_elem_flag_set(eed, BM_ELEM_TAG, BM_edge_is_any_vert_flag_test(eed, BM_ELEM_SELECT));
+ }
+
+ BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_flag_test(eed, BM_ELEM_TAG)) {
BM_edge_select_set(em->bm, eed, TRUE);
}
}
}
else if (selectmode_new == SCE_SELECT_FACE) {
- BMIter liter;
- BMLoop *l;
+ /* select all faces associated with every selected vert */
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_elem_flag_set(efa, BM_ELEM_TAG, BM_face_is_any_vert_flag_test(efa, BM_ELEM_SELECT));
+ }
- /* select all faces associated with every selected vertex */
- efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL);
- for (; efa; efa = BM_iter_step(&iter)) {
- l = BM_iter_new(&liter, em->bm, BM_LOOPS_OF_FACE, efa);
- for (; l; l = BM_iter_step(&liter)) {
- if (BM_elem_flag_test(l->v, BM_ELEM_SELECT)) {
- BM_face_select_set(em->bm, efa, TRUE);
- break;
- }
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
+ BM_face_select_set(em->bm, efa, TRUE);
}
}
}
}
else if (selectmode_old == SCE_SELECT_EDGE) {
if (selectmode_new == SCE_SELECT_FACE) {
- BMIter liter;
- BMLoop *l;
+ /* select all faces associated with every selected edge */
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ BM_elem_flag_set(efa, BM_ELEM_TAG, BM_face_is_any_edge_flag_test(efa, BM_ELEM_SELECT));
+ }
- /* select all faces associated with every selected vertex */
- efa = BM_iter_new(&iter, em->bm, BM_FACES_OF_MESH, NULL);
- for (; efa; efa = BM_iter_step(&iter)) {
- l = BM_iter_new(&liter, em->bm, BM_LOOPS_OF_FACE, efa);
- for (; l; l = BM_iter_step(&liter)) {
- if (BM_elem_flag_test(l->v, BM_ELEM_SELECT)) {
- BM_face_select_set(em->bm, efa, TRUE);
- break;
- }
+ BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+ if (BM_elem_flag_test(efa, BM_ELEM_TAG)) {
+ BM_face_select_set(em->bm, efa, TRUE);
}
}
}
Modified: trunk/blender/source/blender/editors/space_view3d/view3d_header.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/view3d_header.c 2012-11-11 23:04:59 UTC (rev 52121)
+++ trunk/blender/source/blender/editors/space_view3d/view3d_header.c 2012-11-11 23:33:59 UTC (rev 52122)
@@ -319,7 +319,7 @@
View3D *v3d = sa->spacedata.first;
Object *obedit = CTX_data_edit_object(C);
BMEditMesh *em = NULL;
- int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
+ const int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift;
PointerRNA props_ptr;
if (obedit && obedit->type == OB_MESH) {
@@ -348,8 +348,11 @@
case B_SEL_EDGE:
if (em) {
if (shift == 0 || em->selectmode == 0) {
- if ((em->selectmode ^ SCE_SELECT_EDGE) == SCE_SELECT_VERTEX) {
- if (ctrl) EDBM_selectmode_convert(em, SCE_SELECT_VERTEX, SCE_SELECT_EDGE);
+ if (ctrl) {
+ const short selmode_max = highest_order_bit_s(ts->selectmode);
+ if (selmode_max == SCE_SELECT_VERTEX) {
+ EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_EDGE);
+ }
}
em->selectmode = SCE_SELECT_EDGE;
}
@@ -362,11 +365,13 @@
case B_SEL_FACE:
if (em) {
if (shift == 0 || em->selectmode == 0) {
- if (((ts->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_VERTEX) ||
- ((ts->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_EDGE))
- {
- if (ctrl) EDBM_selectmode_convert(em, (ts->selectmode ^ SCE_SELECT_FACE), SCE_SELECT_FACE);
+ if (ctrl) {
+ const short selmode_max = highest_order_bit_s(ts->selectmode);
+ if (ELEM(selmode_max, SCE_SELECT_VERTEX, SCE_SELECT_EDGE)) {
+ EDBM_selectmode_convert(em, selmode_max, SCE_SELECT_FACE);
+ }
}
+
em->selectmode = SCE_SELECT_FACE;
}
ts->selectmode = em->selectmode;
@@ -430,9 +435,15 @@
row = uiLayoutRow(layout, TRUE);
block = uiLayoutGetBlock(row);
- uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Vertex select - Shift-Click for multiple modes");
- uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Edge select - Shift-Click for multiple modes");
- uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, "Face select - Shift-Click for multiple modes");
+ uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL,
+ 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
+ "Vertex select - Shift-Click for multiple modes");
+ uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL,
+ 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
+ "Edge select - Shift-Click for multiple modes, Ctrl-Click expands selection");
+ uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL,
+ 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0,
+ "Face select - Shift-Click for multiple modes, Ctrl-Click expands selection");
}
}
More information about the Bf-blender-cvs
mailing list