Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Vazquez <blendergit@gmail.com>2022-11-08 18:55:59 +0300
committerAntonio Vazquez <blendergit@gmail.com>2022-11-08 18:55:59 +0300
commit4c182aef7ce0e8c26dd2b85c1fa2cd45c2ef64ea (patch)
treeb30ce7abaa65be85c147222cb074571c056b59df
parentbbb1d3e5e7eb4059a0324ae786e1e793852963a9 (diff)
GPencil: Make Sculpt Auto-masking Global and not by Brush
The auto-masking was working by Brush and this was very inconvenient because it was necessary set the options by Brush, now the options are global and can be set at once. Also, the automa-masking now works with `and` logic and not with `or` as before. That means that a stroke must meet all the conditions of the masking. Added new Layer and Material options to masking the strokes using the same Layer/Material of the selected stroke. Before, only Active Layer and Active Material could be masked. The options of masking has been moved to the top-bar using the same design of Mesh Sculpt masking. As result of the changes above, the following props changed: Removed: `brush.gpencil_settings.use_automasking_strokes` `brush.gpencil_settings.use_automasking_layer` `brush.gpencil_settings.use_automasking_material` Added: `tool_settings.gpencil_sculpt.use_automasking_stroke` `tool_settings.gpencil_sculpt.use_automasking_layer_stroke` `tool_settings.gpencil_sculpt.use_automasking_material_stroke` `tool_settings.gpencil_sculpt.use_automasking_layer_active` `tool_settings.gpencil_sculpt.use_automasking_material_active` Reviewed by: Julien Kaspar, Matias Mendiola, Daniel Martinez Lara
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/blender_default.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_grease_pencil_common.py5
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py49
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py4
-rw-r--r--source/blender/editors/gpencil/gpencil_sculpt_paint.c298
-rw-r--r--source/blender/makesdna/DNA_brush_enums.h6
-rw-r--r--source/blender/makesdna/DNA_scene_types.h10
-rw-r--r--source/blender/makesrna/intern/rna_brush.c20
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c30
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");