Weight & Vertex Paint: always respect edit mode hiding on faces.
In some cases it is mandatory to be able to hide parts of the mesh in order to paint certain areas. The Mask modifier doesn't work in weight paint, and edit mode hiding requires using selection, which is not always convenient. This makes the weight and vertex paint modes always respect edit mode hiding like sculpt mode. The change in behavior affects drawing and building paint PBVH. Thus it affects brushes, but not menu operators like Smooth or Normalize. In addition, this makes the Alt-H shortcut available even without any selection enabled, and implements Hide for vertex selection. Differential Revision: https://developer.blender.org/D14163
This commit is contained in:
parent
d9e00fbbf6
commit
e3801a2bd4
Notes:
blender-bot
2023-04-03 10:19:20 +02:00
Referenced by issue #99032, Faces unhide when switching from Edit mode to Weight Paint mode while vertex selection is enabled Referenced by issue #106354, Operators in vertexpaint and weightpaint (incl. the gradient tool) affect hidden (in editmode) parts of the mesh
|
@ -4397,7 +4397,7 @@ def km_face_mask(params):
|
|||
|
||||
items.extend([
|
||||
*_template_items_select_actions(params, "paint.face_select_all"),
|
||||
*_template_items_hide_reveal_actions("paint.face_select_hide", "paint.face_select_reveal"),
|
||||
*_template_items_hide_reveal_actions("paint.face_select_hide", "paint.face_vert_reveal"),
|
||||
("paint.face_select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None),
|
||||
("paint.face_select_linked_pick", {"type": 'L', "value": 'PRESS'},
|
||||
{"properties": [("deselect", False)]}),
|
||||
|
@ -4418,6 +4418,7 @@ def km_weight_paint_vertex_selection(params):
|
|||
|
||||
items.extend([
|
||||
*_template_items_select_actions(params, "paint.vert_select_all"),
|
||||
*_template_items_hide_reveal_actions("paint.vert_select_hide", "paint.face_vert_reveal"),
|
||||
("view3d.select_box", {"type": 'B', "value": 'PRESS'}, None),
|
||||
("view3d.select_lasso", {"type": params.action_mouse, "value": 'CLICK_DRAG', "ctrl": True},
|
||||
{"properties": [("mode", 'ADD')]}),
|
||||
|
@ -4968,6 +4969,7 @@ def km_vertex_paint(params):
|
|||
op_menu("VIEW3D_MT_angle_control", {"type": 'R', "value": 'PRESS'}),
|
||||
("wm.context_menu_enum", {"type": 'E', "value": 'PRESS'},
|
||||
{"properties": [("data_path", 'tool_settings.vertex_paint.brush.stroke_method')]}),
|
||||
("paint.face_vert_reveal", {"type": 'H', "value": 'PRESS', "alt": True}, None),
|
||||
*_template_items_context_panel("VIEW3D_PT_paint_vertex_context_menu", params.context_menu_event),
|
||||
])
|
||||
|
||||
|
@ -5015,6 +5017,7 @@ def km_weight_paint(params):
|
|||
("wm.context_toggle", {"type": 'S', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("data_path", 'tool_settings.weight_paint.brush.use_smooth_stroke')]}),
|
||||
op_menu_pie("VIEW3D_MT_wpaint_vgroup_lock_pie", {"type": 'K', "value": 'PRESS'}),
|
||||
("paint.face_vert_reveal", {"type": 'H', "value": 'PRESS', "alt": True}, None),
|
||||
*_template_items_context_panel("VIEW3D_PT_paint_weight_context_menu", params.context_menu_event),
|
||||
])
|
||||
|
||||
|
|
|
@ -2948,7 +2948,7 @@ def km_face_mask(params):
|
|||
{"properties": [("unselected", False)]}),
|
||||
("paint.face_select_hide", {"type": 'H', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("unselected", True)]}),
|
||||
("paint.face_select_reveal", {"type": 'H', "value": 'PRESS', "alt": True}, None),
|
||||
("paint.face_vert_reveal", {"type": 'H', "value": 'PRESS', "alt": True}, None),
|
||||
("paint.face_select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None),
|
||||
("paint.face_select_linked_pick", {"type": 'L', "value": 'PRESS'},
|
||||
{"properties": [("deselect", False)]}),
|
||||
|
@ -2969,6 +2969,9 @@ def km_weight_paint_vertex_selection(params):
|
|||
|
||||
items.extend([
|
||||
("paint.vert_select_all", {"type": 'A', "value": 'PRESS', "ctrl": True}, None),
|
||||
("paint.vert_select_hide", {"type": 'H', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("unselected", True)]}),
|
||||
("paint.face_vert_reveal", {"type": 'H', "value": 'PRESS', "alt": True}, None),
|
||||
])
|
||||
|
||||
return keymap
|
||||
|
@ -3330,6 +3333,7 @@ def km_vertex_paint(params):
|
|||
("wm.context_toggle", {"type": 'S', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("data_path", 'tool_settings.vertex_paint.brush.use_smooth_stroke')]}),
|
||||
op_menu("VIEW3D_MT_angle_control", {"type": 'R', "value": 'PRESS'}),
|
||||
("paint.face_vert_reveal", {"type": 'H', "value": 'PRESS', "alt": True}, None),
|
||||
*_template_items_context_panel("VIEW3D_PT_paint_vertex_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}),
|
||||
# Tools
|
||||
("paint.brush_select", {"type": 'D', "value": 'PRESS'},
|
||||
|
@ -3362,6 +3366,7 @@ def km_weight_paint(params):
|
|||
{"properties": [("data_path", 'weight_paint_object.data.use_paint_mask')]}),
|
||||
("wm.context_toggle", {"type": 'S', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("data_path", 'tool_settings.weight_paint.brush.use_smooth_stroke')]}),
|
||||
("paint.face_vert_reveal", {"type": 'H', "value": 'PRESS', "alt": True}, None),
|
||||
*_template_items_context_panel("VIEW3D_PT_paint_weight_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}),
|
||||
# Bone selection for combined weight paint + pose mode.
|
||||
("view3d.select", {"type": 'LEFTMOUSE', "value": 'PRESS', "ctrl": True}, None),
|
||||
|
|
|
@ -200,6 +200,11 @@ bool BKE_paint_select_vert_test(struct Object *ob);
|
|||
* (when we don't care if its face or vert)
|
||||
*/
|
||||
bool BKE_paint_select_elem_test(struct Object *ob);
|
||||
/**
|
||||
* Checks if face/vertex hiding is always applied in the current mode.
|
||||
* Returns true in vertex/weight paint.
|
||||
*/
|
||||
bool BKE_paint_always_hide_test(struct Object *ob);
|
||||
|
||||
/* Partial visibility. */
|
||||
|
||||
|
|
|
@ -996,6 +996,12 @@ bool BKE_paint_select_elem_test(Object *ob)
|
|||
return (BKE_paint_select_vert_test(ob) || BKE_paint_select_face_test(ob));
|
||||
}
|
||||
|
||||
bool BKE_paint_always_hide_test(Object *ob)
|
||||
{
|
||||
return ((ob != NULL) && (ob->type == OB_MESH) && (ob->data != NULL) &&
|
||||
(ob->mode & OB_MODE_WEIGHT_PAINT || ob->mode & OB_MODE_VERTEX_PAINT));
|
||||
}
|
||||
|
||||
void BKE_paint_cavity_curve_preset(Paint *p, int preset)
|
||||
{
|
||||
CurveMapping *cumap = NULL;
|
||||
|
@ -2255,12 +2261,7 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
bool respect_hide = true;
|
||||
if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
|
||||
if (!(BKE_paint_select_vert_test(ob) || BKE_paint_select_face_test(ob))) {
|
||||
respect_hide = false;
|
||||
}
|
||||
}
|
||||
const bool respect_hide = true;
|
||||
|
||||
PBVH *pbvh = ob->sculpt->pbvh;
|
||||
if (pbvh != NULL) {
|
||||
|
|
|
@ -235,7 +235,7 @@ bool DRW_object_use_hide_faces(const struct Object *ob)
|
|||
return (me->editflag & ME_EDIT_PAINT_FACE_SEL) != 0;
|
||||
case OB_MODE_VERTEX_PAINT:
|
||||
case OB_MODE_WEIGHT_PAINT:
|
||||
return (me->editflag & (ME_EDIT_PAINT_FACE_SEL | ME_EDIT_PAINT_VERT_SEL)) != 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -425,6 +425,9 @@ void paintvert_select_ungrouped(struct Object *ob, bool extend, bool flush_flags
|
|||
void paintvert_flush_flags(struct Object *ob);
|
||||
void paintvert_tag_select_update(struct bContext *C, struct Object *ob);
|
||||
|
||||
void paintvert_hide(struct bContext *C, struct Object *ob, bool unselected);
|
||||
void paintvert_reveal(struct bContext *C, struct Object *ob, bool select);
|
||||
|
||||
/* mirrtopo */
|
||||
typedef struct MirrTopoStore_t {
|
||||
intptr_t *index_lookup;
|
||||
|
|
|
@ -551,3 +551,54 @@ void paintvert_select_ungrouped(Object *ob, bool extend, bool flush_flags)
|
|||
paintvert_flush_flags(ob);
|
||||
}
|
||||
}
|
||||
|
||||
void paintvert_hide(bContext *C, Object *ob, const bool unselected)
|
||||
{
|
||||
Mesh *const me = BKE_mesh_from_object(ob);
|
||||
|
||||
if (me == NULL || me->totvert == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < me->totvert; i++) {
|
||||
MVert *const mvert = &me->mvert[i];
|
||||
|
||||
if ((mvert->flag & ME_HIDE) == 0) {
|
||||
if (((mvert->flag & SELECT) == 0) == unselected) {
|
||||
mvert->flag |= ME_HIDE;
|
||||
}
|
||||
}
|
||||
|
||||
if (mvert->flag & ME_HIDE) {
|
||||
mvert->flag &= ~SELECT;
|
||||
}
|
||||
}
|
||||
|
||||
BKE_mesh_flush_hidden_from_verts(me);
|
||||
|
||||
paintvert_flush_flags(ob);
|
||||
paintvert_tag_select_update(C, ob);
|
||||
}
|
||||
|
||||
void paintvert_reveal(bContext *C, Object *ob, const bool select)
|
||||
{
|
||||
Mesh *const me = BKE_mesh_from_object(ob);
|
||||
|
||||
if (me == NULL || me->totvert == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < me->totvert; i++) {
|
||||
MVert *const mvert = &me->mvert[i];
|
||||
|
||||
if (mvert->flag & ME_HIDE) {
|
||||
SET_FLAG_FROM_TEST(mvert->flag, select, SELECT);
|
||||
mvert->flag &= ~ME_HIDE;
|
||||
}
|
||||
}
|
||||
|
||||
BKE_mesh_flush_hidden_from_verts(me);
|
||||
|
||||
paintvert_flush_flags(ob);
|
||||
paintvert_tag_select_update(C, ob);
|
||||
}
|
||||
|
|
|
@ -370,10 +370,12 @@ void PAINT_OT_face_select_linked(struct wmOperatorType *ot);
|
|||
void PAINT_OT_face_select_linked_pick(struct wmOperatorType *ot);
|
||||
void PAINT_OT_face_select_all(struct wmOperatorType *ot);
|
||||
void PAINT_OT_face_select_hide(struct wmOperatorType *ot);
|
||||
void PAINT_OT_face_select_reveal(struct wmOperatorType *ot);
|
||||
|
||||
void PAINT_OT_face_vert_reveal(struct wmOperatorType *ot);
|
||||
|
||||
void PAINT_OT_vert_select_all(struct wmOperatorType *ot);
|
||||
void PAINT_OT_vert_select_ungrouped(struct wmOperatorType *ot);
|
||||
void PAINT_OT_vert_select_hide(struct wmOperatorType *ot);
|
||||
|
||||
bool vert_paint_poll(struct bContext *C);
|
||||
bool mask_paint_poll(struct bContext *C);
|
||||
|
|
|
@ -1454,6 +1454,7 @@ void ED_operatortypes_paint(void)
|
|||
/* vertex selection */
|
||||
WM_operatortype_append(PAINT_OT_vert_select_all);
|
||||
WM_operatortype_append(PAINT_OT_vert_select_ungrouped);
|
||||
WM_operatortype_append(PAINT_OT_vert_select_hide);
|
||||
|
||||
/* vertex */
|
||||
WM_operatortype_append(PAINT_OT_vertex_paint_toggle);
|
||||
|
@ -1472,7 +1473,8 @@ void ED_operatortypes_paint(void)
|
|||
WM_operatortype_append(PAINT_OT_face_select_linked_pick);
|
||||
WM_operatortype_append(PAINT_OT_face_select_all);
|
||||
WM_operatortype_append(PAINT_OT_face_select_hide);
|
||||
WM_operatortype_append(PAINT_OT_face_select_reveal);
|
||||
|
||||
WM_operatortype_append(PAINT_OT_face_vert_reveal);
|
||||
|
||||
/* partial visibility */
|
||||
WM_operatortype_append(PAINT_OT_hide_show);
|
||||
|
|
|
@ -749,25 +749,68 @@ void PAINT_OT_face_select_hide(wmOperatorType *ot)
|
|||
ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected objects");
|
||||
}
|
||||
|
||||
static int face_select_reveal_exec(bContext *C, wmOperator *op)
|
||||
static int vert_select_hide_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
const bool select = RNA_boolean_get(op->ptr, "select");
|
||||
const bool unselected = RNA_boolean_get(op->ptr, "unselected");
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
paintface_reveal(C, ob, select);
|
||||
paintvert_hide(C, ob, unselected);
|
||||
ED_region_tag_redraw(CTX_wm_region(C));
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void PAINT_OT_face_select_reveal(wmOperatorType *ot)
|
||||
void PAINT_OT_vert_select_hide(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Face Select Reveal";
|
||||
ot->description = "Reveal hidden faces";
|
||||
ot->idname = "PAINT_OT_face_select_reveal";
|
||||
ot->name = "Vertex Select Hide";
|
||||
ot->description = "Hide selected vertices";
|
||||
ot->idname = "PAINT_OT_vert_select_hide";
|
||||
|
||||
ot->exec = face_select_reveal_exec;
|
||||
ot->poll = facemask_paint_poll;
|
||||
ot->exec = vert_select_hide_exec;
|
||||
ot->poll = vert_paint_poll;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
RNA_def_boolean(ot->srna, "select", true, "Select", "");
|
||||
RNA_def_boolean(
|
||||
ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected vertices");
|
||||
}
|
||||
|
||||
static int face_vert_reveal_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
const bool select = RNA_boolean_get(op->ptr, "select");
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
|
||||
if (BKE_paint_select_vert_test(ob)) {
|
||||
paintvert_reveal(C, ob, select);
|
||||
}
|
||||
else {
|
||||
paintface_reveal(C, ob, select);
|
||||
}
|
||||
|
||||
ED_region_tag_redraw(CTX_wm_region(C));
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static bool face_vert_reveal_poll(bContext *C)
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
|
||||
/* Allow using this operator when no selection is enabled but hiding is applied. */
|
||||
return BKE_paint_select_elem_test(ob) || BKE_paint_always_hide_test(ob);
|
||||
}
|
||||
|
||||
void PAINT_OT_face_vert_reveal(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Reveal Faces/Vertices";
|
||||
ot->description = "Reveal hidden faces and vertices";
|
||||
ot->idname = "PAINT_OT_face_vert_reveal";
|
||||
|
||||
ot->exec = face_vert_reveal_exec;
|
||||
ot->poll = face_vert_reveal_poll;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
RNA_def_boolean(ot->srna,
|
||||
"select",
|
||||
true,
|
||||
"Select",
|
||||
"Specifies whether the newly revealed geometry should be selected");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue