diff options
author | Campbell Barton <ideasman42@gmail.com> | 2011-09-22 20:09:27 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2011-09-22 20:09:27 +0400 |
commit | 7126a4699e3b85f47cd2cc84bdb6a511e9a17f69 (patch) | |
tree | 74af0d993321a75c5a3fb61e6fbeca2011784b24 /source/blender/editors/space_view3d | |
parent | 52a131b6006e131b02225040d0c9e48f5fd8efac (diff) | |
parent | 535668eef01b29b18b71022d1d8f04962251e34c (diff) |
svn merge ^/trunk/blender -r40367:40368 --- raddish weight paint merge
Diffstat (limited to 'source/blender/editors/space_view3d')
-rw-r--r-- | source/blender/editors/space_view3d/drawmesh.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 89 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/space_view3d.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_header.c | 10 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_select.c | 194 |
5 files changed, 292 insertions, 7 deletions
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index 0b671dd9705..63b610a9758 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -550,7 +550,7 @@ static void draw_mesh_text(Scene *scene, Object *ob, int glsl) if(ob->mode & OB_MODE_EDIT) return; else if(ob==OBACT) - if(paint_facesel_test(ob)) + if(paint_facesel_test(ob) || paint_vertsel_test(ob)) return; ddm = mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 4e185d6603a..cbdfc312f09 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -1745,6 +1745,31 @@ void mesh_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BMVert dm->release(dm); } +/* draw callback */ +static void drawSelectedVertices__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) +{ + MVert *mv = &((MVert *)userData)[index]; + + if(!(mv->flag & ME_HIDE)) { + const char sel= mv->flag & SELECT; + + // TODO define selected color + if(sel) { + glColor3f(1.0f, 1.0f, 0.0f); + } + else { + glColor3f(0.0f, 0.0f, 0.0f); + } + + glVertex3fv(co); + } +} + +static void drawSelectedVertices(DerivedMesh *dm, Mesh *me) { + glBegin(GL_POINTS); + dm->foreachMappedVert(dm, drawSelectedVertices__mapFunc, me->mvert); + glEnd(); +} static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, float *v0co, float *v1co) { struct { void (*func)(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index); void *userData; ViewContext vc; int clipVerts; float pmat[4][4], vmat[4][4]; } *data = userData; @@ -3012,7 +3037,16 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D bglPolygonOffset(rv3d->dist, 0.0); } } - + + if(paint_vertsel_test(ob)) { + + glColor3f(0.0f, 0.0f, 0.0f); + glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); + + drawSelectedVertices(dm, ob->data); + + glPointSize(1.0f); + } dm->release(dm); } @@ -6604,6 +6638,32 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, int flag) /* ***************** BACKBUF SEL (BBS) ********* */ +static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) +{ + struct {void* offset; MVert *mvert;} *data = userData; + MVert *mv = &data->mvert[index]; + int offset = (intptr_t) data->offset; + + if (!(mv->flag & ME_HIDE)) { + WM_set_framebuffer_index_color(offset+index); + bglVertex3fv(co); + } +} + +static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset) +{ + struct {void* offset; struct MVert *mvert;} data; + Mesh *me = ob->data; + MVert *mvert = me->mvert; + data.mvert = mvert; + data.offset = (void*)(intptr_t) offset; + glPointSize( UI_GetThemeValuef(TH_VERTEX_SIZE) ); + bglBegin(GL_POINTS); + dm->foreachMappedVert(dm, bbs_obmode_mesh_verts__mapFunc, &data); + bglEnd(); + glPointSize(1.0); +} + static void bbs_mesh_verts__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s)) { void **ptrs = userData; @@ -6712,6 +6772,17 @@ static int bbs_mesh_solid_hide__setDrawOpts(void *userData, int index, int *UNUS } } +// must have called WM_set_framebuffer_index_color beforehand +static int bbs_mesh_solid_hide2__setDrawOpts(void *userData, int index, int *UNUSED(drawSmooth_r)) +{ + Mesh *me = userData; + + if (!(me->mface[index].flag & ME_HIDE)) { + return 1; + } else { + return 0; + } +} static void bbs_mesh_solid(Scene *scene, Object *ob) { DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask); @@ -6770,7 +6841,21 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec EDBM_free_index_arrays(em); } else { - bbs_mesh_solid(scene, ob); + Mesh *me= ob->data; + if(me->editflag & ME_EDIT_VERT_SEL) { + DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask); + glColor3ub(0, 0, 0); + + dm->drawMappedFaces(dm, bbs_mesh_solid_hide2__setDrawOpts, me, 0, GPU_enable_material, NULL); + + + bbs_obmode_mesh_verts(ob, dm, 1); + bm_vertoffs = me->totvert+1; + dm->release(dm); + } + else { + bbs_mesh_solid(scene, ob); + } } break; case OB_CURVE: diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c index d9fcb45881c..b2d430ac7f0 100644 --- a/source/blender/editors/space_view3d/space_view3d.c +++ b/source/blender/editors/space_view3d/space_view3d.c @@ -371,6 +371,10 @@ static void view3d_main_area_init(wmWindowManager *wm, ARegion *ar) keymap= WM_keymap_find(wm->defaultconf, "Face Mask", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); + + keymap= WM_keymap_find(wm->defaultconf, "Weight Paint Vertex Selection", 0, 0); + WM_event_add_keymap_handler(&ar->handlers, keymap); + /* pose is not modal, operator poll checks for this */ keymap= WM_keymap_find(wm->defaultconf, "Pose", 0, 0); WM_event_add_keymap_handler(&ar->handlers, keymap); diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c index e4c316a91f2..4ac5dc2e70c 100644 --- a/source/blender/editors/space_view3d/view3d_header.c +++ b/source/blender/editors/space_view3d/view3d_header.c @@ -501,7 +501,15 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) PointerRNA meshptr; RNA_pointer_create(&ob->id, &RNA_Mesh, ob->data, &meshptr); - uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); + if(ob->mode & (OB_MODE_TEXTURE_PAINT|OB_MODE_VERTEX_PAINT)) { + uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); + } + else { + + row= uiLayoutRow(layout, 1); + uiItemR(row, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); + uiItemR(row, &meshptr, "use_paint_mask_vertex", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); + } } else { const char *str_menu; diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 990df969d68..7dc4112d729 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -54,6 +54,11 @@ #include "BLI_linklist.h" #include "BLI_utildefines.h" +/* vertex box select */ +#include "IMB_imbuf_types.h" +#include "IMB_imbuf.h" +#include "BKE_global.h" + #include "BKE_context.h" #include "BKE_paint.h" #include "BKE_armature.h" @@ -204,6 +209,25 @@ static void EDBM_backbuf_checkAndSelectFaces(BMEditMesh *em, int select) } } + +/* object mode, EM_ prefix is confusing here, rename? */ +static void EDBM_backbuf_checkAndSelectVerts_obmode(Mesh *me, int select) +{ + MVert *mv = me->mvert; + int a; + + if (mv) { + for(a=1; a<=me->totvert; a++, mv++) { + if(EDBM_check_backbuf(a)) { + if(!(mv->flag & ME_HIDE)) { + mv->flag = select?(mv->flag|SELECT):(mv->flag&~SELECT); + } + } + } + } +} +/* object mode, EM_ prefix is confusing here, rename? */ + static void EDBM_backbuf_checkAndSelectTFaces(Mesh *me, int select) { MPoly *mpoly = me->mpoly; @@ -237,7 +261,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)) { return 0; } } @@ -733,6 +757,88 @@ static void do_lasso_select_meta(ViewContext *vc, int mcords[][2], short moves, } } +int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int extend) +{ + Mesh *me; + MVert *mvert; + struct ImBuf *ibuf; + unsigned int *rt; + int a, index; + char *selar; + int sx= rect->xmax-rect->xmin+1; + int sy= rect->ymax-rect->ymin+1; + + me= vc->obact->data; + + if(me==NULL || me->totvert==0 || sx*sy <= 0) + return OPERATOR_CANCELLED; + + selar= MEM_callocN(me->totvert+1, "selar"); + + if (extend == 0 && select) + paintvert_deselect_all_visible(vc->obact, SEL_DESELECT, FALSE); + + view3d_validate_backbuf(vc); + + ibuf = IMB_allocImBuf(sx,sy,32,IB_rect); + rt = ibuf->rect; + glReadPixels(rect->xmin+vc->ar->winrct.xmin, rect->ymin+vc->ar->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect); + if(ENDIAN_ORDER==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf); + + a= sx*sy; + while(a--) { + if(*rt) { + index= WM_framebuffer_to_index(*rt); + if(index<=me->totvert) selar[index]= 1; + } + rt++; + } + + mvert= me->mvert; + for(a=1; a<=me->totvert; a++, mvert++) { + if(selar[a]) { + if(mvert->flag & ME_HIDE); + else { + if(select) mvert->flag |= SELECT; + else mvert->flag &= ~SELECT; + } + } + } + + IMB_freeImBuf(ibuf); + MEM_freeN(selar); + +#ifdef __APPLE__ + glReadBuffer(GL_BACK); +#endif + + paintvert_flush_flags(vc->obact); + + return OPERATOR_FINISHED; +} + +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; + rcti rect; + + if(me==NULL || me->totvert==0) + return; + + if(extend==0 && select) + paintvert_deselect_all_visible(ob, SEL_DESELECT, FALSE); /* flush selection at the end */ + bm_vertoffs= me->totvert+1; /* max index array */ + + lasso_select_boundbox(&rect, mcords, moves); + EDBM_mask_init_backbuf_border(vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax); + + EDBM_backbuf_checkAndSelectVerts_obmode(me, select); + + EDBM_free_backbuf(); + + 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; @@ -795,6 +901,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) @@ -1804,6 +1912,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); } @@ -1840,6 +1951,57 @@ void VIEW3D_OT_select_border(wmOperatorType *ot) WM_operator_properties_gesture_border(ot, TRUE); } +/* much like facesel_face_pick()*/ +/* returns 0 if not found, otherwise 1 */ +static int vertsel_vert_pick(struct bContext *C, Mesh *me, const int mval[2], unsigned int *index, short rect) +{ + ViewContext vc; + view3d_set_viewcontext(C, &vc); + + if (!me || me->totvert==0) + return 0; + + if (rect) { + /* sample rect to increase changes of selecting, so that when clicking + on an face in the backbuf, we can still select a vert */ + + int dist; + *index = view3d_sample_backbuf_rect(&vc, mval, 3, 1, me->totvert+1, &dist,0,NULL, NULL); + } + else { + /* sample only on the exact position */ + *index = view3d_sample_backbuf(&vc, mval[0], mval[1]); + } + + if ((*index)<=0 || (*index)>(unsigned int)me->totvert) + return 0; + + (*index)--; + + return 1; +} + +/* 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) +{ + unsigned int index = 0; + MVert *mv; + if(vertsel_vert_pick(C, me, mval, &index, 1)) { + mv = me->mvert+index; + 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); + return 1; + } + return 0; +} + /* ****** Mouse Select ****** */ @@ -1884,8 +2046,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 + + else if (paint_vertsel_test(obact)) { + retval = mouse_wp_select(C, event->mval, extend, obact, obact->data); + } else { retval = mouse_select(C, event->mval, extend, center, enumerate); + } /* passthrough allows tweaks * FINISHED to signal one operator worked @@ -2010,6 +2176,24 @@ static void paint_facesel_circle_select(ViewContext *vc, int select, const int m } +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; + int bbsel; + /* struct {ViewContext *vc; short select; int mval[2]; float radius; } data = {NULL}; */ /* UNUSED */ + if (me) { + bm_vertoffs= me->totvert+1; /* max index array */ + + bbsel= EDBM_init_backbuf_circle(vc, mval[0], mval[1], (short)(rad+1.0f)); + EDBM_backbuf_checkAndSelectVerts_obmode(me, select==LEFTMOUSE); + EDBM_free_backbuf(); + + paintvert_flush_flags(ob); + } +} + + static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) { struct {ViewContext *vc; short select; int mval[2]; float radius; } *data = userData; @@ -2264,7 +2448,7 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) select= (gesture_mode==GESTURE_MODAL_SELECT); - if( CTX_data_edit_object(C) || paint_facesel_test(obact) || + 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; @@ -2284,6 +2468,10 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op) paint_facesel_circle_select(&vc, select, mval, (float)radius); WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obact->data); } + 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); else |