Fix T68723: GPencil - Split Select mode for Sculpt and Edit mode

Actually, the selection mode is not visible in Sculpt mode when mask is enabled, but still is used.
Also, the mode is shared between Edit mode and Sculpt mode and for meshes the selector is by mode.

This commit splits the select mode in different properties and show the selector in Sculpt mode to define the Select mode. Also, the Select Mask button has been removed and now the Select Mode buttons work equal to Meshes where the select buttons are the mask enable too.

Fixed some old code not valid detected during these changes.

Differential Revision: https://developer.blender.org/D5500
This commit is contained in:
Antonio Vazquez 2019-08-17 16:18:09 +02:00
parent 0e1d4dec7a
commit 85f90ed6fd
Notes: blender-bot 2023-02-14 08:42:53 +01:00
Referenced by commit 5d481d9e55, Fix: greasepencil selection of entire_strokes not working
Referenced by issue #71410, Grease Pencil Sculpt mode  - clone brush and select
Referenced by issue #68723, GPencil: Split Select Mode buttons for Edit and Sculpt modes
11 changed files with 155 additions and 53 deletions

View File

@ -1508,8 +1508,9 @@ class _defs_gpencil_sculpt:
return True
ob = context.active_object
ts = context.scene.tool_settings
return (ob and ob.type == 'GPENCIL' and
(ts.gpencil_sculpt.use_select_mask))
return ob and ob.type == 'GPENCIL' and (ts.use_gpencil_select_mask_point or
ts.use_gpencil_select_mask_stroke or
ts.use_gpencil_select_mask_segment)
@staticmethod
def generate_from_brushes(context):

View File

@ -599,17 +599,20 @@ class VIEW3D_HT_header(Header):
sub.separator(factor=0.4)
sub.prop(tool_settings, "use_gpencil_draw_additive", text="", icon='FREEZE')
# Select mode for Editing
if gpd.use_stroke_edit_mode:
row = layout.row(align=True)
row.prop(tool_settings, "gpencil_selectmode", text="", expand=True)
row.prop(tool_settings, "gpencil_selectmode_edit", text="", expand=True)
# Select mode for Sculpt
if gpd.is_stroke_sculpt_mode :
row = layout.row(align=True)
row.prop(tool_settings, "use_gpencil_select_mask_point", text="")
row.prop(tool_settings, "use_gpencil_select_mask_stroke", text="")
row.prop(tool_settings, "use_gpencil_select_mask_segment", text="")
if gpd.use_stroke_edit_mode or gpd.is_stroke_sculpt_mode or gpd.is_stroke_weight_mode:
row = layout.row(align=True)
if gpd.is_stroke_sculpt_mode:
row.prop(tool_settings.gpencil_sculpt, "use_select_mask", text="")
row.separator()
row.prop(gpd, "use_multiedit", text="", icon='GP_MULTIFRAME_EDITING')
sub = row.row(align=True)
@ -621,8 +624,6 @@ class VIEW3D_HT_header(Header):
if gpd.use_stroke_edit_mode:
row = layout.row(align=True)
row.prop(tool_settings.gpencil_sculpt, "use_select_mask", text="")
row.popover(
panel="VIEW3D_PT_tools_grease_pencil_interpolate",
text="Interpolate",
@ -732,7 +733,10 @@ class VIEW3D_MT_editor_menus(Menu):
# Select Menu
if gp_edit:
if mode_string not in {'PAINT_GPENCIL', 'WEIGHT_GPENCIL'}:
if mode_string == 'SCULPT_GPENCIL' and ts.gpencil_sculpt.use_select_mask:
if mode_string == 'SCULPT_GPENCIL' and \
(ts.use_gpencil_select_mask_point or
ts.use_gpencil_select_mask_stroke or
ts.use_gpencil_select_mask_segment):
layout.menu("VIEW3D_MT_select_gpencil")
elif mode_string == 'EDIT_GPENCIL':
layout.menu("VIEW3D_MT_select_gpencil")

View File

@ -1252,15 +1252,6 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
/* Ensure active frame is set correctly... */
p->gpf = p->gpl->actframe;
/* Restrict eraser to only affecting selected strokes, if the "selection mask" is on
* (though this is only available in editmode)
*/
if (p->gpd->flag & GP_DATA_STROKE_EDITMODE) {
if (ts->gp_sculpt.flag & GP_SCULPT_SETT_FLAG_SELECT_MASK) {
p->flags |= GP_PAINTFLAG_SELECTMASK;
}
}
if (has_layer_to_erase == false) {
p->status = GP_STATUS_CAPTURE;
// if (G.debug & G_DEBUG)

View File

@ -105,6 +105,7 @@ typedef struct tGP_BrushEditData {
eGP_Sculpt_Types brush_type;
eGP_Sculpt_Types brush_type_old;
eGP_Sculpt_Flag flag;
eGP_Sculpt_SelectMaskFlag mask;
/* Space Conversion Data */
GP_SpaceConversion gsc;
@ -1276,6 +1277,9 @@ static bool gpsculpt_brush_init(bContext *C, wmOperator *op)
gso->sa = CTX_wm_area(C);
gso->ar = CTX_wm_region(C);
/* save mask */
gso->mask = ts->gpencil_selectmode_sculpt;
/* multiframe settings */
gso->is_multiframe = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gso->gpd);
gso->use_multiframe_falloff = (ts->gp_sculpt.flag & GP_SCULPT_SETT_FLAG_FRAME_FALLOFF) != 0;
@ -1486,7 +1490,7 @@ static bool gpsculpt_brush_do_stroke(tGP_BrushEditData *gso,
/* Skip if neither one is selected
* (and we are only allowed to edit/consider selected points) */
if ((gso->settings->flag & GP_SCULPT_SETT_FLAG_SELECT_MASK) && (!gso->is_weight_mode)) {
if ((GPENCIL_ANY_SCULPT_MASK(gso->mask)) && (!gso->is_weight_mode)) {
if (!(pt1->flag & GP_SPOINT_SELECT) && !(pt2->flag & GP_SPOINT_SELECT)) {
include_last = false;
continue;

View File

@ -220,6 +220,17 @@ void GPENCIL_OT_editmode_toggle(wmOperatorType *ot)
}
/* set select mode */
static bool gpencil_selectmode_toggle_poll(bContext *C)
{
/* edit only supported with grease pencil objects */
Object *ob = CTX_data_active_object(C);
if ((ob == NULL) || (ob->type != OB_GPENCIL) || (ob->mode != OB_MODE_EDIT_GPENCIL)) {
return false;
}
return ED_operator_view3d_active(C);
}
static int gpencil_selectmode_toggle_exec(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
@ -227,7 +238,7 @@ static int gpencil_selectmode_toggle_exec(bContext *C, wmOperator *op)
const int mode = RNA_int_get(op->ptr, "mode");
/* Just set mode */
ts->gpencil_selectmode = mode;
ts->gpencil_selectmode_edit = mode;
WM_main_add_notifier(NC_SCENE | ND_TOOLSETTINGS, NULL);
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
@ -246,7 +257,7 @@ void GPENCIL_OT_selectmode_toggle(wmOperatorType *ot)
/* callbacks */
ot->exec = gpencil_selectmode_toggle_exec;
ot->poll = gp_strokes_edit3d_poll;
ot->poll = gpencil_selectmode_toggle_poll;
/* flags */
ot->flag = OPTYPE_UNDO | OPTYPE_REGISTER;

View File

@ -635,6 +635,10 @@ struct GP_EditableStrokes_Iter {
} \
(void)0
#define GPENCIL_ANY_SCULPT_MASK(flag) \
((flag & (GP_SCULPT_MASK_SELECTMODE_POINT | GP_SCULPT_MASK_SELECTMODE_STROKE | \
GP_SCULPT_MASK_SELECTMODE_SEGMENT)))
/* ****************************************************** */
#endif /* __GPENCIL_INTERN_H__ */

View File

@ -2128,15 +2128,6 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode, Deps
/* Ensure this gets set... */
p->gpf = p->gpl->actframe;
/* Restrict eraser to only affecting selected strokes, if the "selection mask" is on
* (though this is only available in editmode)
*/
if (p->gpd->flag & GP_DATA_STROKE_EDITMODE) {
if (ts->gp_sculpt.flag & GP_SCULPT_SETT_FLAG_SELECT_MASK) {
p->flags |= GP_PAINTFLAG_SELECTMASK;
}
}
if (has_layer_to_erase == false) {
p->status = GP_STATUS_ERROR;
return;

View File

@ -67,13 +67,30 @@
/** \name Shared Utilities
* \{ */
/* Convert sculpt mask mode to Select mode */
static int gpencil_select_mode_from_sculpt(eGP_Sculpt_SelectMaskFlag mode)
{
if (mode & GP_SCULPT_MASK_SELECTMODE_POINT) {
return GP_SELECTMODE_POINT;
}
else if (mode & GP_SCULPT_MASK_SELECTMODE_STROKE) {
return GP_SELECTMODE_STROKE;
}
else if (GP_SCULPT_MASK_SELECTMODE_SEGMENT) {
return GP_SELECTMODE_SEGMENT;
}
else {
return GP_SELECTMODE_POINT;
}
}
static bool gpencil_select_poll(bContext *C)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
if (GPENCIL_SCULPT_MODE(gpd)) {
ToolSettings *ts = CTX_data_tool_settings(C);
if ((ts->gp_sculpt.flag & GP_SCULPT_SETT_FLAG_SELECT_MASK) == 0) {
if (!(GPENCIL_ANY_SCULPT_MASK(ts->gpencil_selectmode_sculpt))) {
return false;
}
}
@ -917,7 +934,11 @@ static int gpencil_circle_select_exec(bContext *C, wmOperator *op)
{
bGPdata *gpd = ED_gpencil_data_get_active(C);
ToolSettings *ts = CTX_data_tool_settings(C);
const int selectmode = ts->gpencil_selectmode;
Object *ob = CTX_data_active_object(C);
const int selectmode = (ob && ob->mode == OB_MODE_SCULPT_GPENCIL) ?
gpencil_select_mode_from_sculpt(ts->gpencil_selectmode_sculpt) :
ts->gpencil_selectmode_edit;
const float scale = ts->gp_sculpt.isect_threshold;
/* if not edit/sculpt mode, the event is catched but not processed */
@ -1023,12 +1044,18 @@ static int gpencil_generic_select_exec(bContext *C,
GPencilTestFn is_inside_fn,
void *user_data)
{
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ED_gpencil_data_get_active(C);
ToolSettings *ts = CTX_data_tool_settings(C);
ScrArea *sa = CTX_wm_area(C);
const bool strokemode = ((ts->gpencil_selectmode == GP_SELECTMODE_STROKE) &&
const short selectmode = (ob && ob->mode == OB_MODE_SCULPT_GPENCIL) ?
gpencil_select_mode_from_sculpt(ts->gpencil_selectmode_sculpt) :
ts->gpencil_selectmode_edit;
const bool strokemode = ((selectmode == GP_SELECTMODE_STROKE) &&
((gpd->flag & GP_DATA_STROKE_PAINTMODE) == 0));
const bool segmentmode = ((ts->gpencil_selectmode == GP_SELECTMODE_SEGMENT) &&
const bool segmentmode = ((selectmode == GP_SELECTMODE_SEGMENT) &&
((gpd->flag & GP_DATA_STROKE_PAINTMODE) == 0));
const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
const float scale = ts->gp_sculpt.isect_threshold;
@ -1071,7 +1098,6 @@ static int gpencil_generic_select_exec(bContext *C,
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
/* convert point coords to screenspace */
const bool is_inside = is_inside_fn(gps, pt, &gsc, gpstroke_iter.diff_mat, user_data);
if (strokemode == false) {
const bool is_select = (pt->flag & GP_SPOINT_SELECT) != 0;
const int sel_op_result = ED_select_op_action_deselected(sel_op, is_select, is_inside);
@ -1292,6 +1318,7 @@ static void deselect_all_selected(bContext *C)
static int gpencil_select_exec(bContext *C, wmOperator *op)
{
ScrArea *sa = CTX_wm_area(C);
Object *ob = CTX_data_active_object(C);
bGPdata *gpd = ED_gpencil_data_get_active(C);
ToolSettings *ts = CTX_data_tool_settings(C);
const float scale = ts->gp_sculpt.isect_threshold;
@ -1322,8 +1349,12 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
}
/* if select mode is stroke, use whole stroke */
if (ts->gpencil_selectmode == GP_SELECTMODE_STROKE) {
whole = true;
if ((ob) && (ob->mode == OB_MODE_SCULPT_GPENCIL)) {
whole = (bool)(gpencil_select_mode_from_sculpt(ts->gpencil_selectmode_sculpt) ==
GP_SELECTMODE_STROKE);
}
else {
whole = (bool)(ts->gpencil_selectmode_edit == GP_SELECTMODE_STROKE);
}
/* init space conversion stuff */
@ -1424,7 +1455,11 @@ static int gpencil_select_exec(bContext *C, wmOperator *op)
hit_stroke->flag |= GP_STROKE_SELECT;
/* expand selection to segment */
if (ts->gpencil_selectmode == GP_SELECTMODE_SEGMENT) {
const short selectmode = (ob && ob->mode == OB_MODE_SCULPT_GPENCIL) ?
gpencil_select_mode_from_sculpt(ts->gpencil_selectmode_sculpt) :
ts->gpencil_selectmode_edit;
if (selectmode == GP_SELECTMODE_SEGMENT) {
float r_hita[3], r_hitb[3];
bool hit_select = (bool)(hit_point->flag & GP_SPOINT_SELECT);
ED_gpencil_select_stroke_segment(

View File

@ -1125,7 +1125,7 @@ typedef struct GP_Sculpt_Settings {
/* GP_Sculpt_Settings.flag */
typedef enum eGP_Sculpt_SettingsFlag {
/* only affect selected points */
GP_SCULPT_SETT_FLAG_SELECT_MASK = (1 << 0),
GP_SCULPT_SETT_FLAG_DEPRECATED = (1 << 0),
/* apply brush to position */
GP_SCULPT_SETT_FLAG_APPLY_POSITION = (1 << 1),
/* apply brush to strength */
@ -1142,6 +1142,16 @@ typedef enum eGP_Sculpt_SettingsFlag {
GP_SCULPT_SETT_FLAG_PRIMITIVE_CURVE = (1 << 7),
} eGP_Sculpt_SettingsFlag;
/* GP_Sculpt_Settings.gpencil_selectmode_sculpt */
typedef enum eGP_Sculpt_SelectMaskFlag {
/* only affect selected points */
GP_SCULPT_MASK_SELECTMODE_POINT = (1 << 0),
/* only affect selected strokes */
GP_SCULPT_MASK_SELECTMODE_STROKE = (1 << 1),
/* only affect selected segmenst */
GP_SCULPT_MASK_SELECTMODE_SEGMENT = (1 << 2),
} eGP_Sculpt_SelectMaskFlag;
/* Settings for GP Interpolation Operators */
typedef struct GP_Interpolate_Settings {
/** #eGP_Interpolate_SettingsFlag. */
@ -1412,8 +1422,10 @@ typedef struct ToolSettings {
/** Default stroke thickness for annotation strokes. */
short annotate_thickness;
/** Stroke selection mode. */
short gpencil_selectmode;
/** Stroke selection mode for Edit. */
char gpencil_selectmode_edit;
/** Stroke selection mode for Sculpt. */
char gpencil_selectmode_sculpt;
/* Grease Pencil Sculpt */
struct GP_Sculpt_Settings gp_sculpt;

View File

@ -739,6 +739,36 @@ static void rna_GPencilInterpolateSettings_type_set(PointerRNA *ptr, int value)
}
}
static void rna_Gpencil_mask_point_update(Main *UNUSED(bmain),
Scene *UNUSED(scene),
PointerRNA *ptr)
{
ToolSettings *ts = (ToolSettings *)ptr->data;
ts->gpencil_selectmode_sculpt &= ~GP_SCULPT_MASK_SELECTMODE_STROKE;
ts->gpencil_selectmode_sculpt &= ~GP_SCULPT_MASK_SELECTMODE_SEGMENT;
}
static void rna_Gpencil_mask_stroke_update(Main *UNUSED(bmain),
Scene *UNUSED(scene),
PointerRNA *ptr)
{
ToolSettings *ts = (ToolSettings *)ptr->data;
ts->gpencil_selectmode_sculpt &= ~GP_SCULPT_MASK_SELECTMODE_POINT;
ts->gpencil_selectmode_sculpt &= ~GP_SCULPT_MASK_SELECTMODE_SEGMENT;
}
static void rna_Gpencil_mask_segment_update(Main *UNUSED(bmain),
Scene *UNUSED(scene),
PointerRNA *ptr)
{
ToolSettings *ts = (ToolSettings *)ptr->data;
ts->gpencil_selectmode_sculpt &= ~GP_SCULPT_MASK_SELECTMODE_POINT;
ts->gpencil_selectmode_sculpt &= ~GP_SCULPT_MASK_SELECTMODE_STROKE;
}
/* Read-only Iterator of all the scene objects. */
static void rna_Scene_objects_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
@ -3058,13 +3088,39 @@ static void rna_def_tool_settings(BlenderRNA *brna)
prop, "Only Endpoints", "Only use the first and last parts of the stroke for snapping");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
/* Grease Pencil - Select mode */
prop = RNA_def_property(srna, "gpencil_selectmode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "gpencil_selectmode");
/* Grease Pencil - Select mode Edit */
prop = RNA_def_property(srna, "gpencil_selectmode_edit", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "gpencil_selectmode_edit");
RNA_def_property_enum_items(prop, gpencil_selectmode_items);
RNA_def_property_ui_text(prop, "Select Mode", "");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
/* Grease Pencil - Select mode Sculpt */
prop = RNA_def_property(srna, "use_gpencil_select_mask_point", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(
prop, NULL, "gpencil_selectmode_sculpt", GP_SCULPT_MASK_SELECTMODE_POINT);
RNA_def_property_ui_text(prop, "Selection Mask", "Only sculpt selected stroke points");
RNA_def_property_ui_icon(prop, ICON_GP_SELECT_POINTS, 0);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_Gpencil_mask_point_update");
prop = RNA_def_property(srna, "use_gpencil_select_mask_stroke", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(
prop, NULL, "gpencil_selectmode_sculpt", GP_SCULPT_MASK_SELECTMODE_STROKE);
RNA_def_property_ui_text(prop, "Selection Mask", "Only sculpt selected stroke");
RNA_def_property_ui_icon(prop, ICON_GP_SELECT_STROKES, 0);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_Gpencil_mask_stroke_update");
prop = RNA_def_property(srna, "use_gpencil_select_mask_segment", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(
prop, NULL, "gpencil_selectmode_sculpt", GP_SCULPT_MASK_SELECTMODE_SEGMENT);
RNA_def_property_ui_text(
prop, "Selection Mask", "Only sculpt selected stroke points between other strokes");
RNA_def_property_ui_icon(prop, ICON_GP_SELECT_BETWEEN_STROKES, 0);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_Gpencil_mask_segment_update");
/* Annotations - 2D Views Stroke Placement */
prop = RNA_def_property(srna, "annotation_stroke_placement_view2d", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "gpencil_v2d_align");

View File

@ -1420,13 +1420,6 @@ static void rna_def_gpencil_sculpt(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Guide", "");
prop = RNA_def_property(srna, "use_select_mask", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SCULPT_SETT_FLAG_SELECT_MASK);
RNA_def_property_ui_text(prop, "Selection Mask", "Only sculpt selected stroke points");
RNA_def_property_ui_icon(prop, ICON_GP_ONLY_SELECTED, 0);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
prop = RNA_def_property(srna, "use_edit_position", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SCULPT_SETT_FLAG_APPLY_POSITION);
RNA_def_property_ui_text(prop, "Affect Position", "The brush affects the position of the point");