Merged 38822-39182
[blender.git] / source / blender / editors / space_view3d / view3d_select.c
index c6835b0..13af4ff 100644 (file)
@@ -197,6 +197,22 @@ static void EM_backbuf_checkAndSelectFaces(EditMesh *em, int select)
                }
        }
 }
+/* Jason */
+static void EM_backbuf_checkAndSelectTVerts(Mesh *me, int select)
+{
+       MVert *mv = me->mvert;
+       int a;
+
+       if (mv) {
+               for(a=1; a<=me->totvert; a++, mv++) {
+                       if(EM_check_backbuf(a)) {
+                               if(!(mv->flag & ME_HIDE)) {
+                                       mv->flag = select?(mv->flag|SELECT):(mv->flag&~SELECT);
+                               }
+                       }
+               }
+       }
+}
 
 static void EM_backbuf_checkAndSelectTFaces(Mesh *me, int select)
 {
@@ -231,7 +247,7 @@ static int view3d_selectable_data(bContext *C)
                        if (ob->mode & OB_MODE_SCULPT) {
                                return 0;
                        }
-                       if (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT) && !paint_facesel_test(ob)) {
+                       if (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT) && !paint_facesel_test(ob) && !paint_vertsel_test(ob)) {//Jason
                                return 0;
                        }
                }
@@ -625,7 +641,15 @@ static void do_lasso_select_curve(ViewContext *vc, int mcords[][2], short moves,
        ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
        nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data);
 }
+/* Jason */
+static void do_obmode_lasso_select__doSelect(void *userData, MVert *mv, int x, int y)
+{
+       struct { int (*mcords)[2]; short moves; short select; } *data = userData;
 
+       if (lasso_inside(data->mcords, data->moves, x, y)) {
+               mv->flag = data->select?(mv->flag|SELECT):(mv->flag&~SELECT);
+       }
+}
 static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, int x, int y)
 {
        struct { int (*mcords)[2]; short moves; short select; } *data = userData;
@@ -726,7 +750,63 @@ static void do_lasso_select_meta(ViewContext *vc, int mcords[][2], short moves,
                }
        }
 }
+/* Jason */
+static void do_obmode_box_select__doSelect(void *userData, MVert *mv, int x, int y)
+{
+       struct { ViewContext vc; rcti *rect; int select; } *data = userData;
+
+       if (BLI_in_rcti(data->rect, x, y)) {
+               mv->flag = data->select?(mv->flag|SELECT):(mv->flag&~SELECT);
+       }
+}
+/* Jason */
+int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int extend)
+{
+       Object *ob= vc->obact;
+       Mesh *me= ob?ob->data:NULL;
+       int sx= rect->xmax-rect->xmin+1;
+       int sy= rect->ymax-rect->ymin+1;
+
+       struct { ViewContext vc; rcti *rect; int select; } data = {NULL};
+
+       if(me==NULL || me->totvert==0 || sx*sy <= 0)
+               return OPERATOR_CANCELLED;
+
+       if(extend==0 && select)
+               paintvert_deselect_all_visible(ob, SEL_DESELECT, FALSE); /* flush selection at the end */
+
+       ED_view3d_init_mats_rv3d(ob, vc->rv3d);
+       data.vc = *vc;
+       data.rect = rect;
+       data.select= select;
+
+       mesh_obmode_foreachScreenVert(vc, do_obmode_box_select__doSelect, &data, 1);
+
+       paintvert_flush_flags(ob);
+
+       return OPERATOR_FINISHED;
+}
+/* Jason */
+static void do_lasso_select_paintvert(ViewContext *vc, int mcords[][2], short moves, short extend, short select)
+{
+       Object *ob= vc->obact;
+       Mesh *me= ob?ob->data:NULL;
+
+       struct { int (*mcords)[2]; short moves; short select; } data = {NULL};
+
+       if(me==NULL || me->totvert==0)
+               return;
+
+       if(extend==0 && select)
+               paintvert_deselect_all_visible(ob, SEL_DESELECT, FALSE); /* flush selection at the end */
+       ED_view3d_init_mats_rv3d(ob, vc->rv3d);
+       data.select = select;
+       data.mcords = mcords;
+       data.moves= moves;
+       mesh_obmode_foreachScreenVert(vc, do_obmode_lasso_select__doSelect, &data, 1);
 
+       paintvert_flush_flags(ob);
+}
 static void do_lasso_select_paintface(ViewContext *vc, int mcords[][2], short moves, short extend, short select)
 {
        Object *ob= vc->obact;
@@ -789,6 +869,8 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc, int mcords[][2], s
        if(vc->obedit==NULL) { /* Object Mode */
                if(paint_facesel_test(ob))
                        do_lasso_select_paintface(vc, mcords, moves, extend, select);
+               else if(paint_vertsel_test(ob))
+                       do_lasso_select_paintvert(vc, mcords, moves, extend, select);
                else if(ob && ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT))
                        ;
                else if(ob && ob->mode & OB_MODE_PARTICLE_EDIT)
@@ -1792,6 +1874,9 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
                else if(vc.obact && paint_facesel_test(vc.obact)) {
                        ret= do_paintface_box_select(&vc, &rect, select, extend);
                }
+               else if(vc.obact && paint_vertsel_test(vc.obact)) {
+                       ret= do_paintvert_box_select(&vc, &rect, select, extend);
+               }
                else if(vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) {
                        ret= PE_border_select(C, &rect, select, extend);
                }
@@ -1827,6 +1912,69 @@ void VIEW3D_OT_select_border(wmOperatorType *ot)
        /* rna */
        WM_operator_properties_gesture_border(ot, TRUE);
 }
+/*Jason*/
+static void findnearestWPvert__doClosest(void *userData, MVert *mv, int x, int y, int UNUSED(index))
+{
+       struct { MVert *mv; short dist, select; int mval[2]; } *data = userData;
+       float temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
+       if((mv->flag & SELECT)==data->select)
+               temp += 5;
+
+       if(temp<data->dist) {
+               data->dist = temp;
+
+               data->mv = mv;
+       }
+}
+/*Jason*/
+static MVert *findnearestWPvert(ViewContext *vc, Object *obact, Mesh *me, const int mval[2], int sel)
+{
+       /* sel==1: selected gets a disadvantage */
+       struct { MVert *mv; short dist, select; int mval[2]; } data = {NULL};
+
+       data.dist = 100;
+       data.select = sel;
+       data.mval[0]= mval[0];
+       data.mval[1]= mval[1];
+
+       mesh_obmode_foreachScreenVert(vc, findnearestWPvert__doClosest, &data, 1);
+
+       return data.mv;
+}
+/* Jason */
+/* mouse selection in weight paint */
+/* gets called via generic mouse select operator */
+int mouse_wp_select(bContext *C, const int mval[2], short extend, Object *obact, Mesh* me)
+{
+       MVert *mv;
+       ViewContext *vc = NULL;
+       vc = MEM_callocN(sizeof(ViewContext), "wp_m_sel_viewcontext");
+       vc->ar= CTX_wm_region(C);
+       vc->scene= CTX_data_scene(C);
+       vc->v3d= CTX_wm_view3d(C);
+       vc->rv3d= CTX_wm_region_view3d(C);
+       vc->obact= obact;
+       vc->mval[0] = mval[0];
+       vc->mval[1] = mval[1];
+
+       ED_view3d_init_mats_rv3d(obact, vc->rv3d);
+
+       if(mv = findnearestWPvert(vc, obact, me, mval, 1)) {
+               if(extend) {
+                       mv->flag ^= 1;
+               } else {
+                       paintvert_deselect_all_visible(obact, SEL_DESELECT, FALSE);
+                       mv->flag |= 1;
+               }
+               paintvert_flush_flags(obact);
+               WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data);
+
+               MEM_freeN(vc);
+               return 1;
+       }
+       MEM_freeN(vc);
+       return 0;
+}
 
 /* ****** Mouse Select ****** */
 
@@ -1839,6 +1987,9 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
        short center= RNA_boolean_get(op->ptr, "center");
        short enumerate= RNA_boolean_get(op->ptr, "enumerate");
        int     retval = 0;
+       // Jason
+       Mesh *me;
+       Scene *scene = CTX_data_scene(C);
 
        view3d_operator_needs_opengl(C);
        
@@ -1861,8 +2012,12 @@ static int view3d_select_invoke(bContext *C, wmOperator *op, wmEvent *event)
                return PE_mouse_particles(C, event->mval, extend);
        else if(obact && paint_facesel_test(obact))
                retval = paintface_mouse_select(C, obact, event->mval, extend);
-       else
+       /*Jason*/
+       else if (paint_vertsel_test(obact) && (me = (Mesh*)(obact->data))) {
+               retval = mouse_wp_select(C, event->mval, extend, obact, me);
+       } else {
                retval = mouse_select(C, event->mval, extend, center, enumerate);
+       }
 
        /* passthrough allows tweaks
         * FINISHED to signal one operator worked
@@ -1906,6 +2061,18 @@ static void mesh_circle_doSelectVert(void *userData, EditVert *eve, int x, int y
                eve->f = data->select?(eve->f|1):(eve->f&~1);
        }
 }
+/* Jason */
+static void mesh_obmode_circle_doSelectVert(void *userData, MVert *mv, int x, int y, int UNUSED(index))
+{
+       struct {ViewContext *vc; short select; int mval[2]; float radius; } *data = userData;
+       int mx = x - data->mval[0], my = y - data->mval[1];
+       float r = sqrt(mx*mx + my*my);
+
+       if (r<=data->radius) {
+               mv->flag = data->select?(mv->flag|1):(mv->flag&~1);
+       }
+}
+
 static void mesh_circle_doSelectEdge(void *userData, EditEdge *eed, int x0, int y0, int x1, int y1, int UNUSED(index))
 {
        struct {ViewContext *vc; short select; int mval[2]; float radius; } *data = userData;
@@ -1985,6 +2152,27 @@ static void paint_facesel_circle_select(ViewContext *vc, int select, const int m
        }
 }
 
+/* Jason */
+static void paint_vertsel_circle_select(ViewContext *vc, int select, const int mval[2], float rad)
+{
+       Object *ob= vc->obact;
+       Mesh *me = ob?ob->data:NULL;
+
+       struct {ViewContext *vc; short select; int mval[2]; float radius; } data = {NULL};
+       if (me) {
+               ED_view3d_init_mats_rv3d(ob, vc->rv3d);
+               data.radius = rad;
+               data.vc = vc;
+               data.select = select;
+               data.mval[0]= mval[0];
+               data.mval[1]= mval[1];
+
+               mesh_obmode_foreachScreenVert(vc, mesh_obmode_circle_doSelectVert, &data, 1);
+
+               paintvert_flush_flags(ob);
+       }
+}
+
 
 static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y)
 {
@@ -2239,8 +2427,8 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
        int select;
        
        select= (gesture_mode==GESTURE_MODAL_SELECT);
-
-       if( CTX_data_edit_object(C) || paint_facesel_test(obact) ||
+                                                                                                                               // Jason
+       if( CTX_data_edit_object(C) || paint_facesel_test(obact) || paint_vertsel_test(obact) ||
                (obact && (obact->mode & (OB_MODE_PARTICLE_EDIT|OB_MODE_POSE))) )
        {
                ViewContext vc;
@@ -2259,6 +2447,10 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
                else if(paint_facesel_test(obact)) {
                        paint_facesel_circle_select(&vc, select, mval, (float)radius);
                        WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data);
+               }/* Jason */
+               else if(paint_vertsel_test(obact)) {
+                       paint_vertsel_circle_select(&vc, select, mval, (float)radius);
+                       WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data);
                }
                else if(obact->mode & OB_MODE_POSE)
                        pose_circle_select(&vc, select, mval, (float)radius);