diff options
-rw-r--r-- | release/scripts/presets/keyconfig/keymap_data/blender_default.py | 2 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/properties_grease_pencil_common.py | 5 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/space_view3d.py | 49 | ||||
-rw-r--r-- | release/scripts/startup/bl_ui/space_view3d_toolbar.py | 4 | ||||
-rw-r--r-- | source/blender/editors/gpencil/gpencil_sculpt_paint.c | 298 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_brush_enums.h | 6 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 10 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_brush.c | 20 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_sculpt_paint.c | 30 |
9 files changed, 294 insertions, 130 deletions
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py index b83c4916330..60834df285a 100644 --- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py +++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py @@ -3969,6 +3969,8 @@ def km_grease_pencil_stroke_sculpt_mode(params): op_menu("VIEW3D_MT_gpencil_animation", {"type": 'I', "value": 'PRESS'}), # Context menu *_template_items_context_panel("VIEW3D_PT_gpencil_sculpt_context_menu", params.context_menu_event), + # Automasking Pie menu + op_menu_pie("VIEW3D_MT_sculpt_gpencil_automasking_pie", {"type": 'A', "shift": True, "alt": True, "value": 'PRESS'}), ]) return keymap diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py index 38522a1bf84..83bb0f7dd8c 100644 --- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py +++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py @@ -51,11 +51,6 @@ class GreasePencilSculptAdvancedPanel: tool = brush.gpencil_sculpt_tool gp_settings = brush.gpencil_settings - col = layout.column(heading="Auto-Masking", align=True) - col.prop(gp_settings, "use_automasking_stroke", text="Stroke") - col.prop(gp_settings, "use_automasking_layer", text="Layer") - col.prop(gp_settings, "use_automasking_material", text="Material") - if tool in {'SMOOTH', 'RANDOMIZE'}: col = layout.column(heading="Affect", align=True) col.prop(gp_settings, "use_edit_position", text="Position") diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 83f190ee5d9..5aad2d9b363 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -108,7 +108,7 @@ class VIEW3D_HT_tool_header(Header): brush = context.tool_settings.gpencil_sculpt_paint.brush if brush: tool = brush.gpencil_sculpt_tool - if tool != 'CLONE': + if tool in {'SMOOTH', 'RANDOMIZE'}: layout.popover("VIEW3D_PT_tools_grease_pencil_sculpt_brush_popover") layout.popover("VIEW3D_PT_tools_grease_pencil_sculpt_appearance") elif tool_mode == 'WEIGHT_GPENCIL': @@ -837,14 +837,18 @@ class VIEW3D_HT_header(Header): panel="VIEW3D_PT_gpencil_guide", text="Guides", ) - + if object_mode == 'SCULPT_GPENCIL': + layout.popover( + panel="VIEW3D_PT_gpencil_sculpt_automasking", + text="", + icon="MOD_MASK" + ) elif object_mode == 'SCULPT': layout.popover( panel="VIEW3D_PT_sculpt_automasking", text="", icon="MOD_MASK" ) - else: # Transform settings depending on tool header visibility VIEW3D_HT_header.draw_xform_template(layout, context) @@ -5519,6 +5523,22 @@ class VIEW3D_MT_sculpt_automasking_pie(Menu): pie.prop(sculpt, "use_automasking_view_normal", text="View Normal") +class VIEW3D_MT_sculpt_gpencil_automasking_pie(Menu): + bl_label = "Automasking" + + def draw(self, context): + layout = self.layout + pie = layout.menu_pie() + + tool_settings = context.tool_settings + + pie.prop(tool_settings.gpencil_sculpt, "use_automasking_stroke", text="Stroke") + pie.prop(tool_settings.gpencil_sculpt, "use_automasking_layer_stroke", text="Layer") + pie.prop(tool_settings.gpencil_sculpt, "use_automasking_material_stroke", text="Material") + pie.prop(tool_settings.gpencil_sculpt, "use_automasking_layer_active", text="Active Layer") + pie.prop(tool_settings.gpencil_sculpt, "use_automasking_material_active", text="Active Material") + + class VIEW3D_MT_sculpt_face_sets_edit_pie(Menu): bl_label = "Face Sets Edit" @@ -7467,6 +7487,27 @@ def draw_gpencil_material_active(context, layout): row.prop(ma, "name", text="") +class VIEW3D_PT_gpencil_sculpt_automasking(Panel): + bl_space_type = 'VIEW_3D' + bl_region_type = 'HEADER' + bl_label = "Auto-masking" + bl_ui_units_x = 10 + + def draw(self, context): + layout = self.layout + + tool_settings = context.scene.tool_settings + layout.label(text="Auto-masking") + + col = layout.column(align=True) + col.prop(tool_settings.gpencil_sculpt, "use_automasking_stroke", text="Stroke") + col.prop(tool_settings.gpencil_sculpt, "use_automasking_layer_stroke", text="Layer") + col.prop(tool_settings.gpencil_sculpt, "use_automasking_material_stroke", text="Material") + col.separator() + col.prop(tool_settings.gpencil_sculpt, "use_automasking_layer_active", text="Active Layer") + col.prop(tool_settings.gpencil_sculpt, "use_automasking_material_active", text="Active Material") + + class VIEW3D_PT_gpencil_sculpt_context_menu(Panel): bl_space_type = 'VIEW_3D' bl_region_type = 'WINDOW' @@ -8103,6 +8144,7 @@ classes = ( VIEW3D_MT_proportional_editing_falloff_pie, VIEW3D_MT_sculpt_mask_edit_pie, VIEW3D_MT_sculpt_automasking_pie, + VIEW3D_MT_sculpt_gpencil_automasking_pie, VIEW3D_MT_wpaint_vgroup_lock_pie, VIEW3D_MT_sculpt_face_sets_edit_pie, VIEW3D_MT_sculpt_curves, @@ -8117,6 +8159,7 @@ classes = ( VIEW3D_PT_annotation_onion, VIEW3D_PT_gpencil_multi_frame, VIEW3D_PT_gpencil_curve_edit, + VIEW3D_PT_gpencil_sculpt_automasking, VIEW3D_PT_quad_view, VIEW3D_PT_view3d_stereo, VIEW3D_PT_shading, diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index fec156580cf..111fb0d8bae 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -1964,7 +1964,7 @@ class VIEW3D_PT_tools_grease_pencil_sculpt_brush_advanced(GreasePencilSculptAdva return False tool = brush.gpencil_sculpt_tool - return tool != 'CLONE' + return tool in {'SMOOTH', 'RANDOMIZE'} class VIEW3D_PT_tools_grease_pencil_sculpt_brush_popover(GreasePencilSculptAdvancedPanel, View3DPanel, Panel): @@ -1982,7 +1982,7 @@ class VIEW3D_PT_tools_grease_pencil_sculpt_brush_popover(GreasePencilSculptAdvan return False tool = brush.gpencil_sculpt_tool - return tool != 'CLONE' + return tool in {'SMOOTH', 'RANDOMIZE'} # Grease Pencil weight painting tools diff --git a/source/blender/editors/gpencil/gpencil_sculpt_paint.c b/source/blender/editors/gpencil/gpencil_sculpt_paint.c index 37c1524c2ff..ab3edfdd4fa 100644 --- a/source/blender/editors/gpencil/gpencil_sculpt_paint.c +++ b/source/blender/editors/gpencil/gpencil_sculpt_paint.c @@ -68,6 +68,8 @@ #include "gpencil_intern.h" +#define SEARCH_RADIUS_PIXEL 20 + /* ************************************************ */ /* General Brush Editing Context */ @@ -78,6 +80,7 @@ typedef struct tGP_BrushEditData { Main *bmain; Scene *scene; Object *object; + Object *ob_eval; ScrArea *area; ARegion *region; @@ -1181,6 +1184,8 @@ static bool gpencil_sculpt_brush_init(bContext *C, wmOperator *op) } /* Check if some modifier can transform the stroke. */ gso->is_transformed = BKE_gpencil_has_transform_modifiers(ob); + + gso->ob_eval = (Object *)DEG_get_evaluated_id(gso->depsgraph, &ob->id); } else { unit_m4(gso->inv_mat); @@ -1196,9 +1201,13 @@ static bool gpencil_sculpt_brush_init(bContext *C, wmOperator *op) gso->brush = brush; BKE_curvemapping_init(gso->brush->curve); - if (brush->gpencil_settings->sculpt_mode_flag & - (GP_SCULPT_FLAGMODE_AUTOMASK_STROKE | GP_SCULPT_FLAGMODE_AUTOMASK_LAYER | - GP_SCULPT_FLAGMODE_AUTOMASK_MATERIAL)) { + const bool is_automasking = (ts->gp_sculpt.flag & + (GP_SCULPT_SETT_FLAG_AUTOMASK_STROKE | + GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_STROKE | + GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_STROKE | + GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_ACTIVE | + GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_ACTIVE)) != 0; + if (is_automasking) { gso->automasking_strokes = BLI_ghash_ptr_new(__func__); } else { @@ -1604,13 +1613,16 @@ static bool gpencil_sculpt_brush_do_frame(bContext *C, bGPdata *gpd = ob->data; const char tool = gso->brush->gpencil_sculpt_tool; GP_SpaceConversion *gsc = &gso->gsc; + ToolSettings *ts = gso->scene->toolsettings; Brush *brush = gso->brush; const int radius = (brush->flag & GP_BRUSH_USE_PRESSURE) ? gso->brush->size * gso->pressure : gso->brush->size; - const bool is_automasking = (brush->gpencil_settings->sculpt_mode_flag & - (GP_SCULPT_FLAGMODE_AUTOMASK_STROKE | - GP_SCULPT_FLAGMODE_AUTOMASK_LAYER | - GP_SCULPT_FLAGMODE_AUTOMASK_MATERIAL)) != 0; + const bool is_automasking = (ts->gp_sculpt.flag & + (GP_SCULPT_SETT_FLAG_AUTOMASK_STROKE | + GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_STROKE | + GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_STROKE | + GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_ACTIVE | + GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_ACTIVE)) != 0; /* Calc bound box matrix. */ float bound_mat[4][4]; BKE_gpencil_layer_transform_matrix_get(gso->depsgraph, gso->object, gpl, bound_mat); @@ -1743,27 +1755,111 @@ static bool gpencil_sculpt_brush_do_frame(bContext *C, return changed; } +/* Find the stroke nearer to the brush. */ +static void get_nearest_stroke_to_brush(tGP_BrushEditData *gso, + int mval_i[2], + bGPDlayer **r_gpl, + bGPDstroke **r_gps) +{ + const int radius = SEARCH_RADIUS_PIXEL; + + Object *ob_eval = gso->ob_eval; + bGPdata *gpd = (bGPdata *)ob_eval->data; + GP_SpaceConversion *gsc = &gso->gsc; + const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); + float dist = FLT_MAX; + + LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { + if (!BKE_gpencil_layer_is_editable(gpl) || (gpl->actframe == NULL)) { + continue; + } + /* Calculate bound box matrix. */ + float bound_mat[4][4]; + BKE_gpencil_layer_transform_matrix_get(gso->depsgraph, gso->object, gpl, bound_mat); + + bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; + for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { + LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + bGPDstroke *gps_active = (gps->runtime.gps_orig) ? gps->runtime.gps_orig : gps; + if (gps->totpoints == 0) { + continue; + } + /* Check if the color is editable. */ + if (ED_gpencil_stroke_material_editable(gso->object, gpl, gps) == false) { + continue; + } + + /* Check if the stroke collide with brush. */ + if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) { + continue; + } + + bGPDspoint *pt; + int pc2D[2] = {0}; + bGPDspoint npt; + + for (int i = 0; i < gps->totpoints; i++) { + pt = gps->points + i; + gpencil_point_to_world_space(pt, bound_mat, &npt); + gpencil_point_to_xy(gsc, gps, &npt, &pc2D[0], &pc2D[1]); + float d = len_v2v2_int(mval_i, pc2D); + if (d < dist) { + dist = d; + *r_gpl = gpl; + *r_gps = gps_active; + } + } + } + /* If not multi-edit, exit loop. */ + if (!is_multiedit) { + break; + } + } + } +} + /* Get list of Auto-Masking strokes. */ static bool get_automasking_strokes_list(tGP_BrushEditData *gso) { - bGPdata *gpd = gso->gpd; + Object *ob_eval = gso->ob_eval; + bGPdata *gpd = (bGPdata *)ob_eval->data; GP_SpaceConversion *gsc = &gso->gsc; - Brush *brush = gso->brush; + ToolSettings *ts = gso->scene->toolsettings; Object *ob = gso->object; - Material *mat_active = BKE_gpencil_material(ob, ob->actcol); + const eGP_Sculpt_SettingsFlag flag = ts->gp_sculpt.flag; const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd); - const bool is_masking_stroke = (brush->gpencil_settings->sculpt_mode_flag & - GP_SCULPT_FLAGMODE_AUTOMASK_STROKE) != 0; - const bool is_masking_layer = (brush->gpencil_settings->sculpt_mode_flag & - GP_SCULPT_FLAGMODE_AUTOMASK_LAYER) != 0; - const bool is_masking_material = (brush->gpencil_settings->sculpt_mode_flag & - GP_SCULPT_FLAGMODE_AUTOMASK_MATERIAL) != 0; + const bool is_masking_stroke = (flag & GP_SCULPT_SETT_FLAG_AUTOMASK_STROKE) != 0; + const bool is_masking_layer_stroke = (flag & GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_STROKE) != 0; + const bool is_masking_material_stroke = (flag & GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_STROKE) != + 0; + const bool is_masking_layer_active = (flag & GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_ACTIVE) != 0; + const bool is_masking_material_active = (flag & GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_ACTIVE) != + 0; int mval_i[2]; round_v2i_v2fl(mval_i, gso->mval); /* Define a fix number of pixel as cursor radius. */ - const int radius = 10; + const int radius = SEARCH_RADIUS_PIXEL; bGPDlayer *gpl_active = BKE_gpencil_layer_active_get(gpd); + Material *mat_active = BKE_gpencil_material(ob, ob->actcol); + + /* By default use active values. */ + bGPDlayer *gpl_active_stroke = gpl_active; + Material *mat_active_stroke = mat_active; + /* Find nearest stroke to find the layer and material. */ + if (is_masking_layer_stroke || is_masking_material_stroke) { + bGPDlayer *gpl_near = NULL; + bGPDstroke *gps_near = NULL; + get_nearest_stroke_to_brush(gso, mval_i, &gpl_near, &gps_near); + if (gps_near != NULL) { + if (is_masking_layer_stroke) { + gpl_active_stroke = gpl_near; + } + if (is_masking_material_stroke) { + mat_active_stroke = BKE_object_material_get(ob, gps_near->mat_nr + 1); + } + } + } LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) { /* Only editable and visible layers are considered. */ @@ -1777,87 +1873,113 @@ static bool get_automasking_strokes_list(tGP_BrushEditData *gso) bGPDframe *init_gpf = (is_multiedit) ? gpl->frames.first : gpl->actframe; for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) { LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) { + bGPDstroke *gps_active = (gps->runtime.gps_orig) ? gps->runtime.gps_orig : gps; + bool pick_stroke = false; + bool pick_layer_stroke = false; + bool pick_material_stroke = false; + bool pick_layer_active = false; + bool pick_material_active = false; + if (gps->totpoints == 0) { continue; } - /* Check if the color is editable. */ + /* Check if the material is editable. */ if (ED_gpencil_stroke_material_editable(gso->object, gpl, gps) == false) { continue; } - /* Layer Auto-Masking. */ - if ((is_masking_layer) && (gpl == gpl_active)) { - BLI_ghash_insert(gso->automasking_strokes, gps, gps); - continue; + /* Stroke Layer Auto-Masking. */ + if (is_masking_layer_stroke && (gpl == gpl_active_stroke)) { + pick_layer_stroke = true; } - /* Material Auto-Masking. */ - if (is_masking_material) { + /* Active Layer Auto-Masking. */ + if (is_masking_layer_active && (gpl == gpl_active)) { + pick_layer_active = true; + } + /* Stroke Material Auto-Masking. */ + if (is_masking_material_stroke) { Material *mat = BKE_object_material_get(ob, gps->mat_nr + 1); - if (mat == mat_active) { - BLI_ghash_insert(gso->automasking_strokes, gps, gps); - continue; + if (mat == mat_active_stroke) { + pick_material_stroke = true; } } - - /* If Stroke Auto-Masking is not enabled, nothing else to do. */ - if (!is_masking_stroke) { - continue; + /* Active Material Auto-Masking. */ + if (is_masking_material_active) { + Material *mat = BKE_object_material_get(ob, gps->mat_nr + 1); + if (mat == mat_active) { + pick_material_active = true; + } } /* Check if the stroke collide with brush. */ - if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) { - continue; - } - - bGPDspoint *pt1, *pt2; - int pc1[2] = {0}; - int pc2[2] = {0}; - bGPDspoint npt; + if ((is_masking_stroke) && + ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) { - if (gps->totpoints == 1) { - gpencil_point_to_world_space(gps->points, bound_mat, &npt); - gpencil_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]); + bGPDspoint *pt1, *pt2; + int pc1[2] = {0}; + int pc2[2] = {0}; + bGPDspoint npt; - /* Only check if point is inside. */ - if (len_v2v2_int(mval_i, pc1) <= radius) { - BLI_ghash_insert(gso->automasking_strokes, gps, gps); - } - } - else { - /* Loop over the points in the stroke, checking for intersections - * - an intersection means that we touched the stroke. - */ - for (int i = 0; (i + 1) < gps->totpoints; i++) { - /* Get points to work with. */ - pt1 = gps->points + i; - pt2 = gps->points + i + 1; - - /* Check first point. */ - gpencil_point_to_world_space(pt1, bound_mat, &npt); + if (gps->totpoints == 1) { + gpencil_point_to_world_space(gps->points, bound_mat, &npt); gpencil_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]); - if (len_v2v2_int(mval_i, pc1) <= radius) { - BLI_ghash_insert(gso->automasking_strokes, gps, gps); - i = gps->totpoints; - continue; - } - /* Check second point. */ - gpencil_point_to_world_space(pt2, bound_mat, &npt); - gpencil_point_to_xy(gsc, gps, &npt, &pc2[0], &pc2[1]); - if (len_v2v2_int(mval_i, pc2) <= radius) { - BLI_ghash_insert(gso->automasking_strokes, gps, gps); - i = gps->totpoints; - continue; + /* Only check if point is inside. */ + if (len_v2v2_int(mval_i, pc1) <= radius) { + pick_stroke = true; } - - /* Check segment. */ - if (gpencil_stroke_inside_circle(gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) { - BLI_ghash_insert(gso->automasking_strokes, gps, gps); - i = gps->totpoints; - continue; + } + else { + /* Loop over the points in the stroke, checking for intersections + * - an intersection means that we touched the stroke. + */ + for (int i = 0; (i + 1) < gps->totpoints && !pick_stroke; i++) { + /* Get points to work with. */ + pt1 = gps->points + i; + pt2 = gps->points + i + 1; + + /* Check first point. */ + gpencil_point_to_world_space(pt1, bound_mat, &npt); + gpencil_point_to_xy(gsc, gps, &npt, &pc1[0], &pc1[1]); + if (len_v2v2_int(mval_i, pc1) <= radius) { + pick_stroke = true; + i = gps->totpoints; + } + + /* Check second point. */ + gpencil_point_to_world_space(pt2, bound_mat, &npt); + gpencil_point_to_xy(gsc, gps, &npt, &pc2[0], &pc2[1]); + if (len_v2v2_int(mval_i, pc2) <= radius) { + pick_stroke = true; + i = gps->totpoints; + } + + /* Check segment. */ + if (!pick_stroke && gpencil_stroke_inside_circle( + gso->mval, radius, pc1[0], pc1[1], pc2[0], pc2[1])) { + pick_stroke = true; + i = gps->totpoints; + } } } } + /* if the stroke meets all the masking conditions, add to the hash table. */ + if (is_masking_stroke && !pick_stroke) { + continue; + } + if (is_masking_layer_stroke && !pick_layer_stroke) { + continue; + } + if (is_masking_material_stroke && !pick_material_stroke) { + continue; + } + if (is_masking_layer_active && !pick_layer_active) { + continue; + } + if (is_masking_material_active && !pick_material_active) { + continue; + } + BLI_ghash_insert(gso->automasking_strokes, gps_active, gps_active); } /* If not multi-edit, exit loop. */ if (!is_multiedit) { @@ -1877,7 +1999,7 @@ static bool gpencil_sculpt_brush_apply_standard(bContext *C, tGP_BrushEditData * Object *obact = gso->object; bool changed = false; - Object *ob_eval = (Object *)DEG_get_evaluated_id(depsgraph, &obact->id); + Object *ob_eval = gso->ob_eval; bGPdata *gpd = (bGPdata *)ob_eval->data; /* Calculate brush-specific data which applies equally to all points */ @@ -1971,6 +2093,7 @@ static void gpencil_sculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA * { tGP_BrushEditData *gso = op->customdata; Brush *brush = gso->brush; + ToolSettings *ts = gso->scene->toolsettings; const int radius = (brush->flag & GP_BRUSH_USE_PRESSURE) ? gso->brush->size * gso->pressure : gso->brush->size; float mousef[2]; @@ -2012,9 +2135,10 @@ static void gpencil_sculpt_brush_apply(bContext *C, wmOperator *op, PointerRNA * /* Get list of Auto-Masking strokes. */ if ((!gso->automasking_ready) && - (brush->gpencil_settings->sculpt_mode_flag & - (GP_SCULPT_FLAGMODE_AUTOMASK_STROKE | GP_SCULPT_FLAGMODE_AUTOMASK_LAYER | - GP_SCULPT_FLAGMODE_AUTOMASK_MATERIAL))) { + (ts->gp_sculpt.flag & + (GP_SCULPT_SETT_FLAG_AUTOMASK_STROKE | GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_STROKE | + GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_STROKE | GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_ACTIVE | + GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_ACTIVE))) { gso->automasking_ready = get_automasking_strokes_list(gso); } @@ -2082,20 +2206,6 @@ static void gpencil_sculpt_brush_apply_event(bContext *C, wmOperator *op, const if (gso->brush == NULL) { gso->brush = gso->brush_prev; } - Brush *brush = gso->brush; - if (brush->gpencil_settings->sculpt_mode_flag & - (GP_SCULPT_FLAGMODE_AUTOMASK_STROKE | GP_SCULPT_FLAGMODE_AUTOMASK_LAYER | - GP_SCULPT_FLAGMODE_AUTOMASK_MATERIAL)) { - if (gso->automasking_strokes == NULL) { - gso->automasking_strokes = BLI_ghash_ptr_new(__func__); - } - } - else { - if (gso->automasking_strokes != NULL) { - BLI_ghash_free(gso->automasking_strokes, NULL, NULL); - } - gso->automasking_strokes = NULL; - } } else { if (gso->brush_prev != NULL) { diff --git a/source/blender/makesdna/DNA_brush_enums.h b/source/blender/makesdna/DNA_brush_enums.h index 8b889e17762..72357ea6734 100644 --- a/source/blender/makesdna/DNA_brush_enums.h +++ b/source/blender/makesdna/DNA_brush_enums.h @@ -315,12 +315,6 @@ typedef enum eGP_Sculpt_Mode_Flag { GP_SCULPT_FLAGMODE_APPLY_THICKNESS = (1 << 2), /* apply brush to uv data */ GP_SCULPT_FLAGMODE_APPLY_UV = (1 << 3), - /* Stroke Auto-Masking for sculpt. */ - GP_SCULPT_FLAGMODE_AUTOMASK_STROKE = (1 << 4), - /* Layer Auto-Masking for sculpt. */ - GP_SCULPT_FLAGMODE_AUTOMASK_LAYER = (1 << 5), - /* Material Auto-Masking for sculpt. */ - GP_SCULPT_FLAGMODE_AUTOMASK_MATERIAL = (1 << 6), } eGP_Sculpt_Mode_Flag; typedef enum eAutomasking_flag { diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index 28359038be5..8d02b274c65 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1155,6 +1155,16 @@ typedef enum eGP_Sculpt_SettingsFlag { GP_SCULPT_SETT_FLAG_PRIMITIVE_CURVE = (1 << 1), /** Scale thickness. */ GP_SCULPT_SETT_FLAG_SCALE_THICKNESS = (1 << 3), + /* Stroke Auto-Masking for sculpt. */ + GP_SCULPT_SETT_FLAG_AUTOMASK_STROKE = (1 << 4), + /* Stroke Layer Auto-Masking for sculpt. */ + GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_STROKE = (1 << 5), + /* Stroke Material Auto-Masking for sculpt. */ + GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_STROKE = (1 << 6), + /* Active Layer Auto-Masking for sculpt. */ + GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_ACTIVE = (1 << 7), + /* Active Material Auto-Masking for sculpt. */ + GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_ACTIVE = (1 << 8), } eGP_Sculpt_SettingsFlag; /** #GP_Sculpt_Settings.gpencil_selectmode_sculpt */ diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 5ba31070e1d..ce51b52de39 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -1919,26 +1919,6 @@ static void rna_def_gpencil_options(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); - prop = RNA_def_property(srna, "use_automasking_stroke", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna( - prop, NULL, "sculpt_mode_flag", GP_SCULPT_FLAGMODE_AUTOMASK_STROKE); - RNA_def_property_ui_text(prop, "Auto-Masking Strokes", "Mask strokes below brush cursor"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); - - prop = RNA_def_property(srna, "use_automasking_layer", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "sculpt_mode_flag", GP_SCULPT_FLAGMODE_AUTOMASK_LAYER); - RNA_def_property_ui_text(prop, "Auto-Masking Layer", "Mask strokes using active layer"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); - - prop = RNA_def_property(srna, "use_automasking_material", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna( - prop, NULL, "sculpt_mode_flag", GP_SCULPT_FLAGMODE_AUTOMASK_MATERIAL); - RNA_def_property_ui_text(prop, "Auto-Masking Material", "Mask strokes using active material"); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); - /* Material */ prop = RNA_def_property(srna, "material", PROP_POINTER, PROP_NONE); RNA_def_property_struct_type(prop, "Material"); diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index 7ae9e25bab3..c5e7c6a6e91 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -1638,6 +1638,36 @@ static void rna_def_gpencil_sculpt(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + prop = RNA_def_property(srna, "use_automasking_stroke", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SCULPT_SETT_FLAG_AUTOMASK_STROKE); + RNA_def_property_ui_text(prop, "Auto-Masking Strokes", "Affect only strokes below the cursor"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + + prop = RNA_def_property(srna, "use_automasking_layer_stroke", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_STROKE); + RNA_def_property_ui_text(prop, "Auto-Masking Layer", "Affect only strokes below the cursor"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + + prop = RNA_def_property(srna, "use_automasking_material_stroke", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_STROKE); + RNA_def_property_ui_text(prop, "Auto-Masking Material", "Affect only strokes below the cursor"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + + prop = RNA_def_property(srna, "use_automasking_layer_active", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SCULPT_SETT_FLAG_AUTOMASK_LAYER_ACTIVE); + RNA_def_property_ui_text(prop, "Auto-Masking Layer", "Affect only the Active Layer"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + + prop = RNA_def_property(srna, "use_automasking_material_active", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SCULPT_SETT_FLAG_AUTOMASK_MATERIAL_ACTIVE); + RNA_def_property_ui_text(prop, "Auto-Masking Material", "Affect only the Active Material"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL); + /* custom falloff curve */ prop = RNA_def_property(srna, "multiframe_falloff_curve", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "cur_falloff"); |