initial support for 'occlude background geometry' in weight paint mode.
Only support mouse vertex select at the moment.
This commit is contained in:
@@ -70,7 +70,8 @@ class VIEW3D_HT_header(Header):
|
||||
row.prop(toolsettings.particle_edit, "select_mode", text="", expand=True)
|
||||
|
||||
# Occlude geometry
|
||||
if view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH')):
|
||||
if ((view.viewport_shade not in {'BOUNDBOX', 'WIREFRAME'} and (mode == 'PARTICLE_EDIT' or (mode == 'EDIT' and obj.type == 'MESH'))) or
|
||||
(mode == 'WEIGHT_PAINT' and obj.data.use_paint_mask_vertex)):
|
||||
row.prop(view, "use_occlude_geometry", text="")
|
||||
|
||||
# Proportional editing
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
if (ED_mesh_pick_face(C, me, mval, &poly_index, size)) {
|
||||
BLI_assert(me && GS(me->id.name) == ID_ME);
|
||||
|
||||
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;
|
||||
|
||||
int v_idx_best = -1;
|
||||
int v_idx;
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if ((*index) <= 0 || (*index) > (unsigned int)me->totvert)
|
||||
return 0;
|
||||
|
||||
(*index)--;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user