2.5
authorTon Roosendaal <ton@blender.org>
Fri, 30 Jan 2009 18:53:54 +0000 (18:53 +0000)
committerTon Roosendaal <ton@blender.org>
Fri, 30 Jan 2009 18:53:54 +0000 (18:53 +0000)
Edit Mesh Loop select back;
the versions with ALT+Select (edgeloop) or with
ALT+CTRL+Select ('ring'). Hold shift for extend.

source/blender/editors/mesh/editmesh_mods.c
source/blender/editors/mesh/mesh_intern.h
source/blender/editors/mesh/mesh_ops.c

index a49d12179460676d84dad5697ac35151a0ef929e..7bc648a849c74ac0404eec9c402ed001186c9414 100644 (file)
@@ -1921,37 +1921,53 @@ void loop_multiselect(EditMesh *em, int looptype)
                
 /* ***************** MAIN MOUSE SELECTION ************** */
 
-/* just to have the functions nice together */
 
-static void mouse_mesh_loop(ViewContext *vc)
+/* ***************** loop select (non modal) ************** */
+
+static EnumPropertyItem prop_select_types[] = {
+       {0, "LOOP_EXCLUSIVE", "Loop Exclusive", ""},
+       {1, "LOOP_EXTEND", "Loop Extend", ""},
+       {2, "RING_EXCLUSIVE", "Ring Exclusive", ""},
+       {3, "RING_EXTEND", "Ring Extend", ""},
+       {0, NULL, NULL, NULL}
+};
+
+
+static void mouse_mesh_loop(bContext *C, short mval[2], short extend, short ring)
 {
-       EditMesh *em= vc->em;
+       ViewContext vc;
+       EditMesh *em;
        EditEdge *eed;
        int select= 1;
        int dist= 50;
-       int shift= 0, alt= 0, ctrl= 0; // XXX
        
-       eed= findnearestedge(vc, &dist);
+       em_setup_viewcontext(C, &vc);
+       vc.mval[0]= mval[0];
+       vc.mval[1]= mval[1];
+       em= vc.em;
+       
+       eed= findnearestedge(&vc, &dist);
        if(eed) {
-               if (vc->scene->toolsettings->edge_mode == EDGE_MODE_SELECT) {
-                       if(shift==0) EM_clear_flag_all(em, SELECT);
+               /* XXX: should toolsettings do this? */
+               if (vc.scene->toolsettings->edge_mode == EDGE_MODE_SELECT) {
+                       if(extend==0) EM_clear_flag_all(em, SELECT);
                
                        if((eed->f & SELECT)==0) select=1;
-                       else if(shift) select=0;
+                       else if(extend) select=0;
 
                        if(em->selectmode & SCE_SELECT_FACE) {
                                faceloop_select(em, eed, select);
                        }
                        else if(em->selectmode & SCE_SELECT_EDGE) {
-                       if((alt && ctrl))
+                       if(ring)
                                        edgering_select(em, eed, select);
-                       else if(alt)
+                       else
                                        edgeloop_select(em, eed, select);
                        }
                    else if(em->selectmode & SCE_SELECT_VERTEX) {
-                       if((alt && ctrl))
+                       if(ring)
                                        edgering_select(em, eed, select);
-                       else if(alt)
+                       else 
                                        edgeloop_select(em, eed, select);
                        }
 
@@ -1960,18 +1976,18 @@ static void mouse_mesh_loop(ViewContext *vc)
                        
                } 
                else {
-                       int act = (edgetag_context_check(vc->scene, eed)==0);
+                       int act = (edgetag_context_check(vc.scene, eed)==0);
                        int path = 0;
                        
-                       if (alt && ctrl && em->selected.last) {
+                       if (ring && em->selected.last) {
                                EditSelection *ese = em->selected.last;
        
                                if(ese && ese->type == EDITEDGE) {
                                        EditEdge *eed_act;
                                        eed_act = (EditEdge*)ese->data;
                                        if (eed_act != eed) {
-                                               /* If shift is pressed we need to use the last active edge, (if it exists) */
-                                               if (edgetag_shortest_path(vc->scene, em, eed_act, eed)) {
+                                               /* If extend, we need to use the last active edge, (if it exists) */
+                                               if (edgetag_shortest_path(vc.scene, em, eed_act, eed)) {
                                                        EM_remove_selection(em, eed_act, EDITEDGE);
                                                        EM_select_edge(eed_act, 0);
                                                        path = 1;
@@ -1980,7 +1996,7 @@ static void mouse_mesh_loop(ViewContext *vc)
                                }
                        }
                        if (path==0) {
-                               edgetag_context_set(vc->scene, eed, act); /* switch the edge option */
+                               edgetag_context_set(vc.scene, eed, act); /* switch the edge option */
                        }
                        
                        if (act) {
@@ -2000,7 +2016,7 @@ static void mouse_mesh_loop(ViewContext *vc)
                                }
                        }
                        
-                       switch (0) { // XXX scene->toolsettings->edge_mode) {
+                       switch (vc.scene->toolsettings->edge_mode) {
                        case EDGE_MODE_TAG_SEAM:
                                G.f |= G_DRAWSEAMS;
                                break;
@@ -2015,12 +2031,50 @@ static void mouse_mesh_loop(ViewContext *vc)
                                break;
                        }
                        
-//                     DAG_object_flush_update(scene, obedit, OB_RECALC_DATA);
+                       DAG_object_flush_update(vc.scene, vc.obedit, OB_RECALC_DATA);
                }
-                               
+               
+               WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit);
        }
 }
 
+static int mesh_loop_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       ARegion *ar= CTX_wm_region(C);
+       short extend= RNA_int_get(op->ptr, "type");
+       short mval[2], ring= 0; 
+       
+       mval[0]= event->x - ar->winrct.xmin;
+       mval[1]= event->y - ar->winrct.ymin;
+       
+       view3d_operator_needs_opengl(C);
+       
+       /* hmrs, 4 selections in 1 property this way? */
+       if(extend>1) ring= 1;
+       extend &= ~2;
+       
+       mouse_mesh_loop(C, mval, extend, ring);
+       
+       /* allowing tweaks */
+       return OPERATOR_PASS_THROUGH;
+}
+
+void MESH_OT_loop_select(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Loop Select";
+       ot->idname= "MESH_OT_loop_select";
+       
+       /* api callbacks */
+       ot->invoke= mesh_loop_select_invoke;
+       ot->poll= ED_operator_editmesh;
+       
+       /* properties */
+       RNA_def_enum(ot->srna, "type", prop_select_types, 0, "Type", "");
+}
+
+/* ************************************************** */
+
 
 /* here actual select happens */
 /* gets called via generic mouse select operator */
@@ -2030,15 +2084,13 @@ void mouse_mesh(bContext *C, short mval[2], short extend)
        EditVert *eve;
        EditEdge *eed;
        EditFace *efa;
-       int  alt= 0; // XXX
        
        /* setup view context for argument to callbacks */
        em_setup_viewcontext(C, &vc);
        vc.mval[0]= mval[0];
        vc.mval[1]= mval[1];
        
-       if(alt) mouse_mesh_loop(&vc);
-       else if(unified_findnearest(&vc, &eve, &eed, &efa)) {
+       if(unified_findnearest(&vc, &eve, &eed, &efa)) {
                
                if(extend==0) EM_clear_flag_all(vc.em, SELECT);
                
@@ -2089,7 +2141,6 @@ void mouse_mesh(bContext *C, short mval[2], short extend)
 
        WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit);
        
-//     rightmouse_transform();
 }
 
 // XXX should we use CTX_scene(C)->selectmode & SCE_SELECT_FACE like it was in the past ? calls selectconnected_delimit_mesh_all if true
index 44b1bf394461a4e16bc774eb543195a27dfcd662..ee07600fd0a6a54645fba907b4c5efdd09d377a1 100644 (file)
@@ -168,7 +168,7 @@ extern struct EditFace *EM_face_from_faces(EditMesh *em, struct EditFace *efa1,
 
 
 /* ******************* editmesh_mods.c */
-
+void MESH_OT_loop_select(struct wmOperatorType *ot);
 void MESH_OT_de_select_all(struct wmOperatorType *ot);
 void MESH_OT_select_more(struct wmOperatorType *ot);
 void MESH_OT_select_less(struct wmOperatorType *ot);
index 4d25f0901c8685d79bea01e5234ec54dcd316529..a2a8cab8e874cebae00e3728bec054be3c6e9dd0 100644 (file)
@@ -139,7 +139,7 @@ void ED_operatortypes_mesh(void)
        WM_operatortype_append(MESH_OT_edit_faces);
        WM_operatortype_append(MESH_OT_separate);
        WM_operatortype_append(MESH_OT_dupli_extrude_cursor);
-       
+       WM_operatortype_append(MESH_OT_loop_select);
 }
 
 /* note mesh keymap also for other space? */
@@ -148,6 +148,10 @@ void ED_keymap_mesh(wmWindowManager *wm)
        ListBase *keymap= WM_keymap_listbase(wm, "EditMesh", 0, 0);
        
        /* selecting */
+       RNA_int_set(WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT, 0)->ptr, "type", 0);
+       RNA_int_set(WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT, 0)->ptr, "type", 1);
+       RNA_int_set(WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_ALT|KM_CTRL, 0)->ptr, "type", 2);
+       RNA_int_set(WM_keymap_add_item(keymap, "MESH_OT_loop_select", SELECTMOUSE, KM_PRESS, KM_SHIFT|KM_ALT|KM_CTRL, 0)->ptr, "type", 3);
        WM_keymap_add_item(keymap, "MESH_OT_de_select_all", AKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "MESH_OT_select_more", PADPLUSKEY, KM_PRESS, KM_CTRL, 0);
        WM_keymap_add_item(keymap, "MESH_OT_select_less", PADMINUS, KM_PRESS, KM_CTRL, 0);
@@ -161,6 +165,8 @@ void ED_keymap_mesh(wmWindowManager *wm)
        RNA_float_set(WM_keymap_add_item(keymap, "MESH_OT_select_linked_flat_faces", FKEY, KM_PRESS, (KM_CTRL|KM_SHIFT|KM_ALT), 0)->ptr,"sharpness",135.0);
        RNA_float_set(WM_keymap_add_item(keymap, "MESH_OT_select_sharp_edges", SKEY, KM_PRESS, (KM_CTRL|KM_SHIFT|KM_ALT), 0)->ptr,"sharpness",135.0);           
        
+       /* transform keymap already defined, so no tweaks for select */
+       
        /* hide */
        WM_keymap_add_item(keymap, "MESH_OT_hide_mesh", HKEY, KM_PRESS, 0, 0);
        RNA_boolean_set(WM_keymap_add_item(keymap, "MESH_OT_hide_mesh", HKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "swap", 1);