Sculpt: Add global automasking propagation steps #117316

Merged
Hans Goudey merged 8 commits from Sean-Kim/blender:102377-auto-masking into main 2024-01-29 15:39:50 +01:00
10 changed files with 55 additions and 15 deletions

View File

@ -8527,7 +8527,7 @@ class VIEW3D_PT_sculpt_automasking(Panel):
col.prop(sculpt, "use_automasking_boundary_face_sets", text="Face Sets Boundary")
if sculpt.use_automasking_boundary_edges or sculpt.use_automasking_boundary_face_sets:
col.prop(sculpt.brush, "automasking_boundary_edges_propagation_steps")
col.prop(sculpt, "automasking_boundary_edges_propagation_steps")
col.separator()

View File

@ -29,7 +29,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 15
#define BLENDER_FILE_SUBVERSION 16
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and cancel loading the file, showing a warning to

View File

@ -2728,6 +2728,17 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
FOREACH_NODETREE_END;
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 401, 16)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
Sculpt *sculpt = scene->toolsettings->sculpt;
if (sculpt != nullptr) {
Sculpt default_sculpt = *DNA_struct_default_get(Sculpt);
sculpt->automasking_boundary_edges_propagation_steps =
default_sculpt.automasking_boundary_edges_propagation_steps;
}
}
}
/**
* Always bump subversion in BKE_blender_version.h when adding versioning
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.

View File

@ -383,6 +383,10 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
if (idprop) {
IDP_ClearProperty(idprop);
}
if (ts->sculpt) {
Sean-Kim marked this conversation as resolved
Review

This is basically the point of this function, so this comment isn't adding much. I'd suggest removing it.

This is basically the point of this function, so this comment isn't adding much. I'd suggest removing it.
ts->sculpt->automasking_boundary_edges_propagation_steps = 1;
}
}
void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)

View File

@ -185,20 +185,34 @@ static bool is_constrained_by_radius(const Brush *br)
return false;
}
/* Fetch the propogation_steps value, preferring the brush level value over the global sculpt tool
* value. */
Sean-Kim marked this conversation as resolved Outdated

* * value -> * value

` * * value` -> ` * value`
static int boundary_propagation_steps(const Sculpt *sd, const Brush *brush)
{
return brush && brush->automasking_flags &
(BRUSH_AUTOMASKING_BOUNDARY_EDGES | BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS) ?
brush->automasking_boundary_edges_propagation_steps :
sd->automasking_boundary_edges_propagation_steps;
}
/* Determine if the given automasking settings require values to be precomputed and cached. */
static bool needs_factors_cache(const Sculpt *sd, const Brush *brush)
{
const int automasking_flags = calc_effective_bits(sd, brush);
if (automasking_flags & BRUSH_AUTOMASKING_TOPOLOGY && brush && is_constrained_by_radius(brush)) {
return true;
}
if (automasking_flags & (BRUSH_AUTOMASKING_BOUNDARY_EDGES |
BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS | BRUSH_AUTOMASKING_VIEW_NORMAL))
{
if (automasking_flags & BRUSH_AUTOMASKING_VIEW_NORMAL) {
return brush && brush->automasking_boundary_edges_propagation_steps != 1;
}
Sean-Kim marked this conversation as resolved Outdated

Agreed, but how about handling that in a separate PR?

Agreed, but how about handling that in a separate PR?
if (automasking_flags &
(BRUSH_AUTOMASKING_BOUNDARY_EDGES | BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS))
{
return boundary_propagation_steps(sd, brush) != 1;
}
return false;
}
@ -917,10 +931,6 @@ std::unique_ptr<Cache> cache_init(Sculpt *sd, Brush *brush, Object *ob)
(*(float *)SCULPT_vertex_attr_get(vertex, ss->attrs.automasking_factor)) = initial_value;
}
const int boundary_propagation_steps = brush ?
brush->automasking_boundary_edges_propagation_steps :
1;
/* Additive modes. */
if (mode_enabled(sd, brush, BRUSH_AUTOMASKING_TOPOLOGY)) {
SCULPT_vertex_random_access_ensure(ss);
@ -934,13 +944,14 @@ std::unique_ptr<Cache> cache_init(Sculpt *sd, Brush *brush, Object *ob)
init_face_sets_masking(sd, ob);
}
const int steps = boundary_propagation_steps(sd, brush);
if (mode_enabled(sd, brush, BRUSH_AUTOMASKING_BOUNDARY_EDGES)) {
SCULPT_vertex_random_access_ensure(ss);
init_boundary_masking(ob, AUTOMASK_INIT_BOUNDARY_EDGES, boundary_propagation_steps);
init_boundary_masking(ob, AUTOMASK_INIT_BOUNDARY_EDGES, steps);
}
if (mode_enabled(sd, brush, BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS)) {
SCULPT_vertex_random_access_ensure(ss);
init_boundary_masking(ob, AUTOMASK_INIT_BOUNDARY_FACE_SETS, boundary_propagation_steps);
init_boundary_masking(ob, AUTOMASK_INIT_BOUNDARY_FACE_SETS, steps);
}
/* Subtractive modes. */

View File

@ -163,6 +163,8 @@ typedef struct BrushCurvesSculptSettings {
struct CurveMapping *curve_parameter_falloff;
} BrushCurvesSculptSettings;
/** Max number of propagation steps for automasking settings.*/
#define AUTOMASKING_BOUNDARY_EDGES_MAX_PROPAGATION_STEPS 20
typedef struct Brush {
DNA_DEFINE_CXX_METHODS(Brush)

View File

@ -418,6 +418,7 @@
.automasking_start_normal_falloff = 0.25f, \
.automasking_view_normal_limit = 1.570796, /* 0.5 * pi. */ \
.automasking_view_normal_falloff = 0.25f, \
.automasking_boundary_edges_propagation_steps = 1, \
.flags = SCULPT_DYNTOPO_SUBDIVIDE | SCULPT_DYNTOPO_COLLAPSE,\
.paint = {\
.symmetry_flags = PAINT_SYMMETRY_FEATHER,\

View File

@ -1107,9 +1107,9 @@ typedef struct Sculpt {
float constant_detail;
float detail_percent;
int automasking_boundary_edges_propagation_steps;
int automasking_cavity_blur_steps;
float automasking_cavity_factor;
char _pad[4];
float automasking_start_normal_limit, automasking_start_normal_falloff;
float automasking_view_normal_limit, automasking_view_normal_falloff;

View File

@ -3183,8 +3183,8 @@ static void rna_def_brush(BlenderRNA *brna)
prop = RNA_def_property(
srna, "automasking_boundary_edges_propagation_steps", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, nullptr, "automasking_boundary_edges_propagation_steps");
RNA_def_property_range(prop, 1, 20);
RNA_def_property_ui_range(prop, 1, 20, 1, 3);
RNA_def_property_range(prop, 1, AUTOMASKING_BOUNDARY_EDGES_MAX_PROPAGATION_STEPS);
RNA_def_property_ui_range(prop, 1, AUTOMASKING_BOUNDARY_EDGES_MAX_PROPAGATION_STEPS, 1, -1);
RNA_def_property_ui_text(prop,
"Propagation Steps",
"Distance where boundary edge automasking is going to protect vertices "

View File

@ -876,6 +876,17 @@ static void rna_def_sculpt(BlenderRNA *brna)
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr);
} while ((++entry)->identifier);
prop = RNA_def_property(
srna, "automasking_boundary_edges_propagation_steps", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, nullptr, "automasking_boundary_edges_propagation_steps");
RNA_def_property_range(prop, 1, AUTOMASKING_BOUNDARY_EDGES_MAX_PROPAGATION_STEPS);
RNA_def_property_ui_range(prop, 1, AUTOMASKING_BOUNDARY_EDGES_MAX_PROPAGATION_STEPS, 1, -1);
RNA_def_property_ui_text(prop,
"Propagation Steps",
"Distance where boundary edge automasking is going to protect vertices "
"from the fully masked edge");
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr);
prop = RNA_def_property(srna, "automasking_cavity_factor", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, nullptr, "automasking_cavity_factor");
RNA_def_property_ui_text(prop, "Cavity Factor", "The contrast of the cavity mask");