diff options
author | Campbell Barton <ideasman42@gmail.com> | 2012-12-23 05:54:11 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2012-12-23 05:54:11 +0400 |
commit | 0ac66ada2d307ca8e7c82ea5b47ff73611cff55f (patch) | |
tree | 029bb1cedd86ffeed1fe86a7aa9ac48b56a1249c /source/blender/editors/mesh/meshtools.c | |
parent | 806720507e7e86ef1227a37146b3718ba027f036 (diff) |
initial support for 'occlude background geometry' in weight paint mode.
Only support mouse vertex select at the moment.
Diffstat (limited to 'source/blender/editors/mesh/meshtools.c')
-rw-r--r-- | source/blender/editors/mesh/meshtools.c | 82 |
1 files changed, 67 insertions, 15 deletions
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; } |