From 0ac66ada2d307ca8e7c82ea5b47ff73611cff55f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 23 Dec 2012 01:54:11 +0000 Subject: initial support for 'occlude background geometry' in weight paint mode. Only support mouse vertex select at the moment. --- source/blender/editors/include/ED_mesh.h | 6 +- source/blender/editors/mesh/editface.c | 2 +- source/blender/editors/mesh/meshtools.c | 82 ++++++++++++++++++---- source/blender/editors/sculpt_paint/paint_vertex.c | 10 +-- source/blender/editors/space_view3d/drawobject.c | 8 ++- .../blender/editors/space_view3d/view3d_select.c | 5 +- 6 files changed, 86 insertions(+), 27 deletions(-) (limited to 'source') diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 1b4a67d38c0..f5ab002e0ef 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -291,9 +291,9 @@ int mesh_get_x_mirror_vert(struct Object *ob, int index); struct BMVert *editbmesh_get_x_mirror_vert(struct Object *ob, struct BMEditMesh *em, struct BMVert *eve, const float co[3], int index); int *mesh_get_x_mirror_faces(struct Object *ob, struct BMEditMesh *em); -int ED_mesh_pick_vert(struct bContext *C, struct Mesh *me, const int mval[2], unsigned int *index, int size); -int ED_mesh_pick_face(struct bContext *C, struct Mesh *me, const int mval[2], unsigned int *index, int size); -int ED_mesh_pick_face_vert(struct bContext *C, struct Mesh *me, struct Object *ob, const int mval[2], unsigned int *index, int size); +int ED_mesh_pick_vert(struct bContext *C, struct Object *ob, const int mval[2], unsigned int *index, int size, int use_zbuf); +int ED_mesh_pick_face(struct bContext *C, struct Object *ob, const int mval[2], unsigned int *index, int size); +int ED_mesh_pick_face_vert(struct bContext *C, struct Object *ob, const int mval[2], unsigned int *index, int size); #define ED_MESH_PICK_DEFAULT_VERT_SIZE 50 #define ED_MESH_PICK_DEFAULT_FACE_SIZE 3 diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 29139c5154f..11226b38cbb 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -477,7 +477,7 @@ int paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], in /* Get the face under the cursor */ me = BKE_mesh_from_object(ob); - if (!ED_mesh_pick_face(C, me, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) + if (!ED_mesh_pick_face(C, ob, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) return 0; if (index >= me->totpoly) diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 773331d20f8..d798dfb6ccb 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -1165,9 +1165,12 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em) * * \return boolean TRUE == Found */ -int ED_mesh_pick_face(bContext *C, Mesh *me, const int mval[2], unsigned int *index, int size) +int ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size) { ViewContext vc; + Mesh *me = ob->data; + + BLI_assert(me && GS(me->id.name) == ID_ME); if (!me || me->totpoly == 0) return 0; @@ -1197,11 +1200,14 @@ int ED_mesh_pick_face(bContext *C, Mesh *me, const int mval[2], unsigned int *in * Use when the back buffer stores face index values. but we want a vert. * This gets the face then finds the closest vertex to mval. */ -int ED_mesh_pick_face_vert(bContext *C, Mesh *me, Object *ob, const int mval[2], unsigned int *index, int size) +int ED_mesh_pick_face_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size) { unsigned int poly_index; + Mesh *me = ob->data; + + BLI_assert(me && GS(me->id.name) == ID_ME); - if (ED_mesh_pick_face(C, me, mval, &poly_index, size)) { + if (ED_mesh_pick_face(C, ob, mval, &poly_index, size)) { Scene *scene = CTX_data_scene(C); struct ARegion *ar = CTX_wm_region(C); @@ -1250,31 +1256,77 @@ int ED_mesh_pick_face_vert(bContext *C, Mesh *me, Object *ob, const int mval[2], * * \return boolean TRUE == Found */ -int ED_mesh_pick_vert(bContext *C, Mesh *me, const int mval[2], unsigned int *index, int size) +int ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size, int use_zbuf) { ViewContext vc; + Mesh *me = ob->data; + + BLI_assert(me && GS(me->id.name) == ID_ME); if (!me || me->totvert == 0) return 0; view3d_set_viewcontext(C, &vc); - if (size > 0) { - /* sample rect to increase chances of selecting, so that when clicking - * on an face in the backbuf, we can still select a vert */ + if (use_zbuf) { + if (size > 0) { + /* sample rect to increase chances of selecting, so that when clicking + * on an face in the backbuf, we can still select a vert */ - float dummy_dist; - *index = view3d_sample_backbuf_rect(&vc, mval, size, 1, me->totvert + 1, &dummy_dist, 0, NULL, NULL); + float dummy_dist; + *index = view3d_sample_backbuf_rect(&vc, mval, size, 1, me->totvert + 1, &dummy_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)--; } else { - /* sample only on the exact position */ - *index = view3d_sample_backbuf(&vc, mval[0], mval[1]); - } + /* derived mesh to find deformed locations */ + DerivedMesh *dm = mesh_get_derived_final(vc.scene, ob, CD_MASK_BAREMESH); + struct ARegion *ar = vc.ar; - if ((*index) <= 0 || (*index) > (unsigned int)me->totvert) - return 0; + int v_idx_best = -1; + int v_idx; - (*index)--; + + if (dm == NULL) { + return 0; + } + + if (dm->getVertCo) { + /* find the vert closest to 'mval' */ + const float mval_f[2] = {(float)mval[0], + (float)mval[1]}; + float len_best = FLT_MAX; + + v_idx = me->totvert - 1; + do { + float co[3], sco[2], len; + dm->getVertCo(dm, v_idx, co); + mul_m4_v3(ob->obmat, co); + if (ED_view3d_project_float_global(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { + len = len_squared_v2v2(mval_f, sco); + if (len < len_best) { + len_best = len; + v_idx_best = v_idx; + } + } + } while (v_idx--); + } + + dm->release(dm); + + if (v_idx_best != -1) { + *index = v_idx_best; + return 1; + } + } return 1; } diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 359486a4a8d..63f5b7e6904 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1037,15 +1037,15 @@ static int weight_sample_invoke(bContext *C, wmOperator *op, wmEvent *event) view3d_operator_needs_opengl(C); if (use_vert_sel) { - if (ED_mesh_pick_vert(C, me, event->mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE)) { + if (ED_mesh_pick_vert(C, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE, TRUE)) { v_idx_best = index; } } else { - if (ED_mesh_pick_face_vert(C, me, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) { + if (ED_mesh_pick_face_vert(C, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) { v_idx_best = index; } - else if (ED_mesh_pick_face(C, me, event->mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) { + else if (ED_mesh_pick_face(C, vc.obact, event->mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) { /* this relies on knowning the internal worksings of ED_mesh_pick_face_vert() */ BKE_report(op->reports, RPT_WARNING, "The modifier used does not support deformed locations"); } @@ -1126,13 +1126,13 @@ static EnumPropertyItem *weight_paint_sample_enum_itemf(bContext *C, PointerRNA view3d_operator_needs_opengl(C); if (use_vert_sel) { - if (ED_mesh_pick_vert(C, me, mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE)) { + if (ED_mesh_pick_vert(C, vc.obact, mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE, TRUE)) { MDeformVert *dvert = &me->dvert[index]; found |= weight_paint_sample_enum_itemf__helper(dvert, defbase_tot, groups); } } else { - if (ED_mesh_pick_face(C, me, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) { + if (ED_mesh_pick_face(C, vc.obact, mval, &index, ED_MESH_PICK_DEFAULT_FACE_SIZE)) { MPoly *mp = &me->mpoly[index]; unsigned int fidx = mp->totloop - 1; diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 01759fff74f..91f25c960e9 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -3244,11 +3244,15 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D } if (is_obact && paint_vertsel_test(ob)) { - + const int use_depth = (v3d->flag & V3D_ZBUF_SELECT); glColor3f(0.0f, 0.0f, 0.0f); glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE)); - + + if (!use_depth) glDisable(GL_DEPTH_TEST); + else bglPolygonOffset(rv3d->dist, 1.0); drawSelectedVertices(dm, ob->data); + if (!use_depth) glEnable(GL_DEPTH_TEST); + else bglPolygonOffset(rv3d->dist, 0.0); glPointSize(1.0f); } diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index d37042fa2ec..c08df884d4f 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -2142,11 +2142,14 @@ void VIEW3D_OT_select_border(wmOperatorType *ot) /* gets called via generic mouse select operator */ static int mouse_weight_paint_vertex_select(bContext *C, const int mval[2], short extend, short deselect, short toggle, Object *obact) { + View3D *v3d = CTX_wm_view3d(C); + const int use_zbuf = (v3d->flag & V3D_ZBUF_SELECT); + Mesh *me = obact->data; /* already checked for NULL */ unsigned int index = 0; MVert *mv; - if (ED_mesh_pick_vert(C, me, mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE)) { + if (ED_mesh_pick_vert(C, obact, mval, &index, ED_MESH_PICK_DEFAULT_VERT_SIZE, use_zbuf)) { mv = &me->mvert[index]; if (extend) { mv->flag |= SELECT; -- cgit v1.2.3