Sculpt: Add global automasking propagation steps #117316
|
@ -8527,7 +8527,7 @@ class VIEW3D_PT_sculpt_automasking(Panel):
|
||||||
col.prop(sculpt, "use_automasking_boundary_face_sets", text="Face Sets Boundary")
|
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:
|
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()
|
col.separator()
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ extern "C" {
|
||||||
|
|
||||||
/* Blender file format version. */
|
/* Blender file format version. */
|
||||||
#define BLENDER_FILE_VERSION BLENDER_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
|
/* 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
|
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||||
|
|
|
@ -2728,6 +2728,17 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||||
FOREACH_NODETREE_END;
|
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
|
* Always bump subversion in BKE_blender_version.h when adding versioning
|
||||||
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.
|
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.
|
||||||
|
|
|
@ -383,6 +383,10 @@ static void blo_update_defaults_scene(Main *bmain, Scene *scene)
|
||||||
if (idprop) {
|
if (idprop) {
|
||||||
IDP_ClearProperty(idprop);
|
IDP_ClearProperty(idprop);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ts->sculpt) {
|
||||||
Sean-Kim marked this conversation as resolved
|
|||||||
|
ts->sculpt->automasking_boundary_edges_propagation_steps = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
|
void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template)
|
||||||
|
|
|
@ -185,20 +185,34 @@ static bool is_constrained_by_radius(const Brush *br)
|
||||||
return false;
|
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
Hans Goudey
commented
` * * 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)
|
static bool needs_factors_cache(const Sculpt *sd, const Brush *brush)
|
||||||
{
|
{
|
||||||
|
|
||||||
const int automasking_flags = calc_effective_bits(sd, brush);
|
const int automasking_flags = calc_effective_bits(sd, brush);
|
||||||
|
|
||||||
if (automasking_flags & BRUSH_AUTOMASKING_TOPOLOGY && brush && is_constrained_by_radius(brush)) {
|
if (automasking_flags & BRUSH_AUTOMASKING_TOPOLOGY && brush && is_constrained_by_radius(brush)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (automasking_flags & (BRUSH_AUTOMASKING_BOUNDARY_EDGES |
|
if (automasking_flags & BRUSH_AUTOMASKING_VIEW_NORMAL) {
|
||||||
BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS | BRUSH_AUTOMASKING_VIEW_NORMAL))
|
|
||||||
{
|
|
||||||
return brush && brush->automasking_boundary_edges_propagation_steps != 1;
|
return brush && brush->automasking_boundary_edges_propagation_steps != 1;
|
||||||
}
|
}
|
||||||
Sean-Kim marked this conversation as resolved
Outdated
Hans Goudey
commented
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;
|
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;
|
(*(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. */
|
/* Additive modes. */
|
||||||
if (mode_enabled(sd, brush, BRUSH_AUTOMASKING_TOPOLOGY)) {
|
if (mode_enabled(sd, brush, BRUSH_AUTOMASKING_TOPOLOGY)) {
|
||||||
SCULPT_vertex_random_access_ensure(ss);
|
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);
|
init_face_sets_masking(sd, ob);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int steps = boundary_propagation_steps(sd, brush);
|
||||||
if (mode_enabled(sd, brush, BRUSH_AUTOMASKING_BOUNDARY_EDGES)) {
|
if (mode_enabled(sd, brush, BRUSH_AUTOMASKING_BOUNDARY_EDGES)) {
|
||||||
SCULPT_vertex_random_access_ensure(ss);
|
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)) {
|
if (mode_enabled(sd, brush, BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS)) {
|
||||||
SCULPT_vertex_random_access_ensure(ss);
|
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. */
|
/* Subtractive modes. */
|
||||||
|
|
|
@ -163,6 +163,8 @@ typedef struct BrushCurvesSculptSettings {
|
||||||
struct CurveMapping *curve_parameter_falloff;
|
struct CurveMapping *curve_parameter_falloff;
|
||||||
} BrushCurvesSculptSettings;
|
} BrushCurvesSculptSettings;
|
||||||
|
|
||||||
|
/** Max number of propagation steps for automasking settings.*/
|
||||||
|
#define AUTOMASKING_BOUNDARY_EDGES_MAX_PROPAGATION_STEPS 20
|
||||||
typedef struct Brush {
|
typedef struct Brush {
|
||||||
DNA_DEFINE_CXX_METHODS(Brush)
|
DNA_DEFINE_CXX_METHODS(Brush)
|
||||||
|
|
||||||
|
|
|
@ -418,6 +418,7 @@
|
||||||
.automasking_start_normal_falloff = 0.25f, \
|
.automasking_start_normal_falloff = 0.25f, \
|
||||||
.automasking_view_normal_limit = 1.570796, /* 0.5 * pi. */ \
|
.automasking_view_normal_limit = 1.570796, /* 0.5 * pi. */ \
|
||||||
.automasking_view_normal_falloff = 0.25f, \
|
.automasking_view_normal_falloff = 0.25f, \
|
||||||
|
.automasking_boundary_edges_propagation_steps = 1, \
|
||||||
.flags = SCULPT_DYNTOPO_SUBDIVIDE | SCULPT_DYNTOPO_COLLAPSE,\
|
.flags = SCULPT_DYNTOPO_SUBDIVIDE | SCULPT_DYNTOPO_COLLAPSE,\
|
||||||
.paint = {\
|
.paint = {\
|
||||||
.symmetry_flags = PAINT_SYMMETRY_FEATHER,\
|
.symmetry_flags = PAINT_SYMMETRY_FEATHER,\
|
||||||
|
|
|
@ -1107,9 +1107,9 @@ typedef struct Sculpt {
|
||||||
float constant_detail;
|
float constant_detail;
|
||||||
float detail_percent;
|
float detail_percent;
|
||||||
|
|
||||||
|
int automasking_boundary_edges_propagation_steps;
|
||||||
int automasking_cavity_blur_steps;
|
int automasking_cavity_blur_steps;
|
||||||
float automasking_cavity_factor;
|
float automasking_cavity_factor;
|
||||||
char _pad[4];
|
|
||||||
|
|
||||||
float automasking_start_normal_limit, automasking_start_normal_falloff;
|
float automasking_start_normal_limit, automasking_start_normal_falloff;
|
||||||
float automasking_view_normal_limit, automasking_view_normal_falloff;
|
float automasking_view_normal_limit, automasking_view_normal_falloff;
|
||||||
|
|
|
@ -3183,8 +3183,8 @@ static void rna_def_brush(BlenderRNA *brna)
|
||||||
prop = RNA_def_property(
|
prop = RNA_def_property(
|
||||||
srna, "automasking_boundary_edges_propagation_steps", PROP_INT, PROP_UNSIGNED);
|
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_int_sdna(prop, nullptr, "automasking_boundary_edges_propagation_steps");
|
||||||
RNA_def_property_range(prop, 1, 20);
|
RNA_def_property_range(prop, 1, AUTOMASKING_BOUNDARY_EDGES_MAX_PROPAGATION_STEPS);
|
||||||
RNA_def_property_ui_range(prop, 1, 20, 1, 3);
|
RNA_def_property_ui_range(prop, 1, AUTOMASKING_BOUNDARY_EDGES_MAX_PROPAGATION_STEPS, 1, -1);
|
||||||
RNA_def_property_ui_text(prop,
|
RNA_def_property_ui_text(prop,
|
||||||
"Propagation Steps",
|
"Propagation Steps",
|
||||||
"Distance where boundary edge automasking is going to protect vertices "
|
"Distance where boundary edge automasking is going to protect vertices "
|
||||||
|
|
|
@ -876,6 +876,17 @@ static void rna_def_sculpt(BlenderRNA *brna)
|
||||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr);
|
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr);
|
||||||
} while ((++entry)->identifier);
|
} 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);
|
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_float_sdna(prop, nullptr, "automasking_cavity_factor");
|
||||||
RNA_def_property_ui_text(prop, "Cavity Factor", "The contrast of the cavity mask");
|
RNA_def_property_ui_text(prop, "Cavity Factor", "The contrast of the cavity mask");
|
||||||
|
|
Loading…
Reference in New Issue
This is basically the point of this function, so this comment isn't adding much. I'd suggest removing it.