Sculpt: UI updates and fixed hard edge mode setting

* Brush editor tab now defaults to old
  interface, with two options:
  - Advanced, which shows more options
  - Edit Mode, which shows workspace visibility buttons
* Hard edge mode (which forcibly sets face set slide to 0
  and enables preserve faceset boundarys) now works again.
* Smooth_strength_factor is now a brush channel with
  inheritance set to true.
* Alt-smooth now restores the hard edge mode and
  smooth_strength_factor from the active brush context.
  While both are default inherited from toolsetting defaults,
  it can be quite confusing if either have inheritance unset
  by the user in the Smooth brush.
This commit is contained in:
Joseph Eagar 2021-09-28 09:46:32 -07:00
parent b825fb4625
commit d1b0677817
25 changed files with 309 additions and 190 deletions

View File

@ -166,11 +166,15 @@ class UnifiedPaintPanel:
def channel_unified(layout, context, brush, prop_name, icon='NONE', pressure=True, text=None,
slider=False, header=False, show_reorder=False, expand=None, toolsettings_only=False, ui_editing=True):
""" Generalized way of adding brush options to the UI,
along with their pen pressure setting and global toggle, if they exist. """
along with their pen pressure setting and global toggle"""
if context.mode != "SCULPT":
return UnifiedPaintPanel.prop_unified(layout, context, brush, prop_name, icon=icon, text=text, slider=slider, header=header, expand=expand)
if not context.tool_settings.unified_paint_settings.brush_editor_mode:
ui_editing = False
show_reorder = False
if prop_name == "size":
prop_name = "radius"
elif prop_name == "use_locked_size":
@ -261,7 +265,7 @@ class UnifiedPaintPanel:
#row.prop(ch, "ui_order", text="")
if ch.type == "CURVE":
row.prop(finalch.curve, "curve_preset")
row.prop(finalch.curve, "curve_preset", text=text)
if finalch.curve.curve_preset == "CUSTOM":
path2 = path + ".curve.curve"
template_curve(layout, finalch.curve, "curve", path2)
@ -415,8 +419,6 @@ class UnifiedPaintPanel:
@staticmethod
def prop_unified_color(parent, context, brush, prop_name, *, text=None):
if context.mode == 'SCULPT':
# def channel_unified(layout, context, brush, prop_name, icon='NONE', pressure=True, text=None,
# slider=False, header=False, expand=None, toolsettings_only=False):
return UnifiedPaintPanel.channel_unified(parent, context, brush, prop_name, text=text)
@ -824,6 +826,11 @@ def brush_settings(layout, context, brush, popover=False):
mode = UnifiedPaintPanel.get_brush_mode(context)
layout.prop(context.tool_settings.unified_paint_settings, "brush_editor_mode")
layout.prop(context.tool_settings.unified_paint_settings, "brush_editor_advanced")
advanced = context.tool_settings.unified_paint_settings.brush_editor_advanced
### Draw simple settings unique to each paint mode. ###
brush_shared_settings(layout, context, brush, popover)
@ -832,24 +839,25 @@ def brush_settings(layout, context, brush, popover=False):
capabilities = brush.sculpt_capabilities
sculpt_tool = brush.sculpt_tool
# normal_radius_factor
UnifiedPaintPanel.prop_unified(
layout,
context,
brush,
"normal_radius_factor",
slider=True,
)
if context.preferences.experimental.use_sculpt_tools_tilt and capabilities.has_tilt:
if advanced:
# normal_radius_factor
UnifiedPaintPanel.prop_unified(
layout,
context,
brush,
"tilt_strength_factor",
"normal_radius_factor",
slider=True,
)
if context.preferences.experimental.use_sculpt_tools_tilt and capabilities.has_tilt:
UnifiedPaintPanel.prop_unified(
layout,
context,
brush,
"tilt_strength_factor",
slider=True,
)
UnifiedPaintPanel.prop_unified(
layout,
context,
@ -878,28 +886,34 @@ def brush_settings(layout, context, brush, popover=False):
slider=True,
)
#box.prop(brush, "boundary_smooth_factor")
#box.prop(brush, "use_weighted_smooth")
#box.prop(brush, "preserve_faceset_boundary")
if advanced:
UnifiedPaintPanel.prop_unified(box, context, brush, "boundary_smooth_factor", slider=True)
UnifiedPaintPanel.prop_unified(box, context, brush, "use_weighted_smooth")
UnifiedPaintPanel.prop_unified(box, context, brush, "preserve_faceset_boundary")
UnifiedPaintPanel.prop_unified(box, context, brush, "boundary_smooth_factor", slider=True)
UnifiedPaintPanel.prop_unified(box, context, brush, "use_weighted_smooth")
UnifiedPaintPanel.prop_unified(box, context, brush, "preserve_faceset_boundary")
if brush.channels["preserve_faceset_boundary"].bool_value:
UnifiedPaintPanel.prop_unified(box, context, brush, "autosmooth_fset_slide", slider=True)
if 1: #brush.preserve_faceset_boundary:
UnifiedPaintPanel.prop_unified(box, context, brush, "autosmooth_fset_slide", slider=True)
#box.prop(brush, "autosmooth_fset_slide")
box.prop(brush, "use_custom_auto_smooth_spacing", text="Custom Spacing")
if brush.use_custom_auto_smooth_spacing:
UnifiedPaintPanel.prop_unified(
if advanced:
UnifiedPaintPanel.prop_unified(
box,
context,
brush,
"auto_smooth_spacing",
"autosmooth_use_spacing",
slider=True,
text="Spacing"
)
text="Custom Spacing"
)
if brush.use_custom_auto_smooth_spacing:
UnifiedPaintPanel.prop_unified(
box,
context,
brush,
"auto_smooth_spacing",
slider=True,
text="Spacing"
)
UnifiedPaintPanel.prop_unified(
box,
context,
@ -907,19 +921,21 @@ def brush_settings(layout, context, brush, popover=False):
"auto_smooth_projection",
slider=True
)
UnifiedPaintPanel.prop_unified(
box,
context,
brush,
"auto_smooth_radius_factor",
slider=True
)
UnifiedPaintPanel.channel_unified(
box,
context,
brush,
"autosmooth_falloff_curve"
)
if advanced:
UnifiedPaintPanel.prop_unified(
box,
context,
brush,
"auto_smooth_radius_factor",
slider=True
)
UnifiedPaintPanel.channel_unified(
box,
context,
brush,
"autosmooth_falloff_curve"
)
elif brush.sculpt_tool == "SMOOTH":
UnifiedPaintPanel.prop_unified(
layout,
@ -947,33 +963,35 @@ def brush_settings(layout, context, brush, popover=False):
"topology_rake_factor",
slider=True,
text="Topology Rake"
)
box.prop(brush, "use_custom_topology_rake_spacing", text="Custom Spacing")
)
if advanced:
box.prop(brush, "use_custom_topology_rake_spacing", text="Custom Spacing")
if brush.channels["topology_rake_use_spacing"].bool_value:
UnifiedPaintPanel.prop_unified(
box,
context,
brush,
"topology_rake_spacing",
slider=True,
text="Spacing"
)
if brush.channels["topology_rake_use_spacing"].bool_value:
UnifiedPaintPanel.prop_unified(
box,
context,
brush,
"topology_rake_spacing",
slider=True,
text="Spacing"
"topology_rake_projection",
slider=True
)
UnifiedPaintPanel.prop_unified(
box,
context,
brush,
"topology_rake_radius_scale",
slider=True
)
UnifiedPaintPanel.prop_unified(
box,
context,
brush,
"topology_rake_projection",
slider=True
)
UnifiedPaintPanel.prop_unified(
box,
context,
brush,
"topology_rake_radius_scale",
slider=True
)
UnifiedPaintPanel.channel_unified(
box,
@ -982,12 +1000,14 @@ def brush_settings(layout, context, brush, popover=False):
"topology_rake_mode",
expand=True
)
UnifiedPaintPanel.channel_unified(
box,
context,
brush,
"topology_rake_falloff_curve"
)
if advanced:
UnifiedPaintPanel.channel_unified(
box,
context,
brush,
"topology_rake_falloff_curve"
)
#box.prop(brush, "use_curvature_rake")
box.prop(brush, "ignore_falloff_for_topology_rake")

View File

@ -433,7 +433,7 @@ class VIEW3D_PT_tools_brush_settings_channels(Panel, View3DPaintBrushPanel):
class VIEW3D_PT_tools_brush_settings_channels_preview(Panel, View3DPaintBrushPanel):
bl_context = ".paint_common"
bl_parent_id = "VIEW3D_PT_tools_brush_settings"
bl_label = "Settings Preview"
bl_label = "Workspace Settings Preview"
@classmethod
def poll(cls, context):
@ -513,7 +513,7 @@ class VIEW3D_PT_tools_persistent_base_channels(Panel, View3DPaintPanel):
ch = UnifiedPaintPanel.get_channel(context, brush, "use_persistent")
capabilities = sculpt.brush.sculpt_capabilities
capabilities = brush.sculpt_capabilities
ok = context.mode == "SCULPT"
ok = ok and ch and ch.show_in_workspace
@ -1201,6 +1201,7 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
tool_settings = context.tool_settings
sculpt = tool_settings.sculpt
brush = sculpt.brush
col = layout.column(heading="Display", align=True)
col.prop(sculpt, "show_low_resolution")
@ -1208,11 +1209,17 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
col.prop(sculpt, "use_fast_draw")
col.prop(sculpt, "use_deform_only")
col.prop(sculpt, "show_sculpt_pivot")
col.prop(sculpt, "smooth_strength_factor")
UnifiedPaintPanel.channel_unified(
layout.column(),
context,
brush,
"smooth_strength_factor", ui_editing=False, slider=True)
#col.prop(sculpt, "smooth_strength_factor")
col.separator()
brush = sculpt.brush
UnifiedPaintPanel.channel_unified(
layout.column(),
context,

View File

@ -163,6 +163,9 @@ void BKE_brush_default_input_curves_set(struct Brush *brush);
{ \
CHECK_TYPE_ANY(brush, struct Brush *); \
*(char *)POINTER_OFFSET(brush, (p)->runtime.tool_offset) = tool; \
if ((p)->runtime.ob_mode == OB_MODE_SCULPT) { \
BKE_brush_builtin_patch(brush, tool); \
} \
} \
((void)0)

View File

@ -72,6 +72,8 @@ struct LibraryForeachIDData;
BKE_brush_channelset_get_final_float(childset, parentset, MAKE_BUILTIN_CH_NAME(channel), mapdata)
#define BRUSHSET_GET_INT(chset, channel, mapdata) \
BKE_brush_channelset_get_int(chset, MAKE_BUILTIN_CH_NAME(channel), mapdata)
#define BRUSHSET_GET_FINAL_INT(child, parent, channel, mapdata) \
BKE_brush_channelset_get_final_int(child, parent, MAKE_BUILTIN_CH_NAME(channel), mapdata)
#define BRUSHSET_ENSURE_BUILTIN(chset, channel) \
BKE_brush_channelset_ensure_builtin(chset, MAKE_BUILTIN_CH_NAME(channel))
#define BRUSHSET_SET_FLOAT(chset, channel, val) \

View File

@ -63,6 +63,8 @@ static void brush_init_data(ID *id)
MEMCPY_STRUCT_AFTER(brush, DNA_struct_default_get(Brush), id);
brush->channels = BKE_brush_channelset_create();
/* enable fake user by default */
id_fake_user_set(&brush->id);
@ -167,6 +169,10 @@ static void brush_make_local(Main *bmain, ID *id, const int flags)
bool is_local = false, is_lib = false;
if (brush->channels) {
brush->channels = BKE_brush_channelset_copy(brush->channels);
}
/* - only lib users: do nothing (unless force_local is set)
* - only local users: set flag
* - mixed: make copy

View File

@ -130,19 +130,21 @@ places in rna_engine_codebase are relevent:
MAKE_FLOAT_EX_FLAG(dyntopo_radius_scale, "Radius Scale", "Ratio between the brush radius and the radius that is going to be "
"used for DynTopo", 1.0f, 0.001f, 5.0f, 0.01f, 2.0f, false, BRUSH_CHANNEL_INHERIT)
MAKE_FLOAT_EX(projection, "Projection", "Amount of volume preserving projection", 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, false)
MAKE_FLOAT_EX(autosmooth_projection, "Projection", "Amount of volume preserving projection", 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, false)
MAKE_FLOAT_EX(topology_rake_projection, "Projection", "Amount of volume preserving projection", 0.975f, 0.0f, 1.0f, 0.0f, 1.0f, false)
MAKE_FLOAT_EX(autosmooth_projection, "Auto-Smooth Projection", "Amount of volume preserving projection", 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, false)
MAKE_FLOAT_EX(topology_rake_projection, "Rake Projection", "Amount of volume preserving projection", 0.975f, 0.0f, 1.0f, 0.0f, 1.0f, false)
MAKE_FLOAT(fset_slide, "Face Set Projection", "Stick face set boundaries to surface of mesh", 1.0f, 0.0f, 1.0f)
MAKE_FLOAT(boundary_smooth, "Boundary Smooth", "Smooth hard boundaries", 0.0f, 0.0f, 1.0f)
MAKE_BOOL(topology_rake_use_spacing, "Use Spacing", "Use custom spacing for topology rake", false)
MAKE_BOOL(autosmooth_use_spacing, "Use Spacing", "Use custom spacing for autosmooth", false)
MAKE_FLOAT_EX(topology_rake_spacing, "Spacing", "Topology rake stroke spacing", 13.0f, 0.05f, 1000.0f, 0.1f, 300.0f, false)
MAKE_FLOAT_EX(autosmooth_spacing, "Spacing", "Autosmooth stroke spacing", 13.0f, 0.05f, 1000.0f, 0.1f, 300.0f, false)
MAKE_BOOL(topology_rake_use_spacing, "Use Rake Spacing", "Use custom spacing for topology rake", false)
MAKE_BOOL(autosmooth_use_spacing, "Use Auto-Smooth Spacing", "Use custom spacing for autosmooth", false)
MAKE_FLOAT_EX(topology_rake_spacing, "Rake Spacing", "Topology rake stroke spacing", 13.0f, 0.05f, 1000.0f, 0.1f, 300.0f, false)
MAKE_FLOAT_EX(autosmooth_spacing, "Auto-Smooth Spacing", "Autosmooth stroke spacing", 13.0f, 0.05f, 1000.0f, 0.1f, 300.0f, false)
MAKE_ENUM(topology_rake_mode, "Topology Rake Mode", "", 1, _({
{0, "BRUSH_DIRECTION", ICON_NONE, "Stroke", "Stroke Direction"},
{1, "CURVATURE", ICON_NONE, "Curvature", "Follow mesh curvature"},
{-1},
}))
}))
MAKE_FLOAT_EX_EX(smooth_strength_factor, "Smooth Strength", "Factor to control the strength of shift-smooth", 0.1f, 0.0f, 10.0f, 0.0f, 2.0f, false, false, BRUSH_CHANNEL_INHERIT)
MAKE_FLAGS_EX(automasking, "Automasking", "", 0, _({
{BRUSH_AUTOMASKING_BOUNDARY_EDGES, "BOUNDARY_EDGE", ICON_NONE, "Boundary Edges", ""},
@ -197,8 +199,8 @@ MAKE_FLOAT_EX(plane_offset, "Plane Offset", "Adjust plane on which the brush act
MAKE_BOOL(original_normal, "Original Normal", "When locked keep using normal of surface where stroke was initiated", false)
MAKE_BOOL(original_plane, "Original Plane", "When locked keep using the plane origin of surface where stroke was initiated", false)
MAKE_BOOL(use_weighted_smooth, "Weight By Area", "Weight by face area to get a smoother result", true)
MAKE_BOOL(preserve_faceset_boundary, "Preserve Faceset Boundary", "Preserve face set boundaries", true)
MAKE_BOOL(hard_edge_mode, "Hard Edge Mode", "Forces all brushes into hard edge face set mode (sets face set slide to 0)", false)
MAKE_BOOL_EX(preserve_faceset_boundary, "Preserve Faceset Boundary", "Preserve face set boundaries", true, BRUSH_CHANNEL_INHERIT)
MAKE_BOOL_EX(hard_edge_mode, "Hard Edge Mode", "Forces all brushes into hard edge face set mode (sets face set slide to 0)", false, BRUSH_CHANNEL_INHERIT)
MAKE_BOOL(grab_silhouette, "Grab Silhouette", "Grabs trying to automask the silhouette of the object", false)
MAKE_FLOAT_EX_FLAG(dyntopo_detail_percent, "Detail Percent", "Detail Percent", 25.0f, 0.0f, 1000.0f, 0.0f, 1000.0f, false, BRUSH_CHANNEL_INHERIT)
MAKE_FLOAT_EX_FLAG(dyntopo_detail_range, "Detail Range", "Detail Range", 0.45f, 0.01f, 0.99f, 0.01f, 0.99f, false, BRUSH_CHANNEL_INHERIT)

View File

@ -887,15 +887,19 @@ void BKE_brush_channel_set_int(BrushChannel *ch, int val)
ch->ivalue = val;
}
int BKE_brush_channelset_get_final_int(BrushChannelSet *brushset,
BrushChannelSet *toolset,
int BKE_brush_channelset_get_final_int(BrushChannelSet *child,
BrushChannelSet *parent,
const char *idname,
BrushMappingData *mapdata)
{
BrushChannel *ch = BKE_brush_channelset_lookup(brushset, idname);
if (!parent) {
return BKE_brush_channelset_get_int(child, idname, mapdata);
}
BrushChannel *ch = BKE_brush_channelset_lookup(child, idname);
if (!ch || (ch->flag & BRUSH_CHANNEL_INHERIT)) {
BrushChannel *pch = BKE_brush_channelset_lookup(toolset, idname);
BrushChannel *pch = BKE_brush_channelset_lookup(parent, idname);
if (pch) {
return BKE_brush_channel_get_int(pch, mapdata);
@ -911,15 +915,19 @@ int BKE_brush_channelset_get_final_int(BrushChannelSet *brushset,
return 0;
}
void BKE_brush_channelset_set_final_int(BrushChannelSet *brushset,
BrushChannelSet *toolset,
void BKE_brush_channelset_set_final_int(BrushChannelSet *child,
BrushChannelSet *parent,
const char *idname,
int value)
{
BrushChannel *ch = BKE_brush_channelset_lookup(brushset, idname);
BrushChannel *ch = BKE_brush_channelset_lookup(child, idname);
if (!parent) {
BKE_brush_channelset_set_int(child, idname, value);
}
if (!ch || (ch->flag & BRUSH_CHANNEL_INHERIT)) {
BrushChannel *pch = BKE_brush_channelset_lookup(toolset, idname);
BrushChannel *pch = BKE_brush_channelset_lookup(parent, idname);
if (pch) {
BKE_brush_channel_set_int(pch, value);
@ -1354,28 +1362,30 @@ BrushCommand *BKE_brush_command_init(BrushCommand *command, int tool)
command->tool = tool;
ADDCH("spacing");
ADDCH("radius");
ADDCH("strength");
ADDCH("hard_edge_mode");
switch (tool) {
case SCULPT_TOOL_DRAW:
ADDCH("radius");
ADDCH("strength");
break;
case SCULPT_TOOL_SMOOTH:
ADDCH("radius");
ADDCH("strength");
ADDCH("fset_slide");
ADDCH("boundary_smooth");
ADDCH("projection");
ADDCH("boundary_smooth");
ADDCH("fset_slide");
ADDCH("preserve_faceset_boundary");
break;
case SCULPT_TOOL_TOPOLOGY_RAKE:
ADDCH("radius");
ADDCH("strength");
// ADDCH("fset_slide");
// ADDCH("boundary_smooth");
ADDCH("fset_slide");
ADDCH("preserve_faceset_boundary");
ADDCH("boundary_smooth");
ADDCH("projection");
ADDCH("topology_rake_mode");
break;
case SCULPT_TOOL_DYNTOPO:
ADDCH("fset_slide");
ADDCH("preserve_faceset_boundary");
break;
}
@ -1477,6 +1487,29 @@ static void bke_builtin_commandlist_create_paint(Brush *brush,
// float
}
void BKE_builtin_apply_hard_edge_mode(BrushChannelSet *chset, bool do_apply)
{
if (!do_apply) {
return;
}
// hard edge mode overrides fset_slide to be 0.0.
BrushChannel *ch = BRUSHSET_LOOKUP(chset, fset_slide);
if (ch) {
// clear inheritance flag
ch->flag &= ~BRUSH_CHANNEL_INHERIT;
ch->fvalue = 0.0f;
}
// make sure preserve faceset boundaries is on
ch = BRUSHSET_LOOKUP(chset, preserve_faceset_boundary);
if (ch) {
ch->flag &= ~BRUSH_CHANNEL_INHERIT;
ch->ivalue = 1;
}
}
void BKE_builtin_commandlist_create(Brush *brush,
BrushChannelSet *chset,
BrushCommandList *cl,
@ -1486,6 +1519,8 @@ void BKE_builtin_commandlist_create(Brush *brush,
BrushCommand *cmd;
BrushChannel *ch;
bool hard_edge_mode = BRUSHSET_GET_INT(chset, hard_edge_mode, mapdata);
/* add main tool */
if (ELEM(tool, SCULPT_TOOL_PAINT, SCULPT_TOOL_SMEAR)) {
bke_builtin_commandlist_create_paint(brush, chset, cl, tool, mapdata);
@ -1494,12 +1529,14 @@ void BKE_builtin_commandlist_create(Brush *brush,
cmd = BKE_brush_commandlist_add(cl, chset, true);
BKE_brush_command_init(cmd, tool);
BKE_builtin_apply_hard_edge_mode(cmd->params, hard_edge_mode);
float radius = BKE_brush_channelset_get_float(chset, "radius", mapdata);
bool no_autosmooth = ELEM(
brush->sculpt_tool, SCULPT_TOOL_BOUNDARY, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_MASK);
bool no_rake = no_autosmooth;
bool no_rake = ELEM(brush->sculpt_tool, SCULPT_TOOL_BOUNDARY, SCULPT_TOOL_MASK);
;
/* build autosmooth command */
float autosmooth_scale = BKE_brush_channelset_get_float(
@ -1530,6 +1567,7 @@ void BKE_builtin_commandlist_create(Brush *brush,
float autosmooth = BKE_brush_channelset_get_float(chset, "autosmooth", mapdata);
if (!no_autosmooth && autosmooth > 0.0f) {
cmd = BKE_brush_command_init(BKE_brush_commandlist_add(cl, chset, true), SCULPT_TOOL_SMOOTH);
BKE_builtin_apply_hard_edge_mode(cmd->params, hard_edge_mode);
BrushChannel *ch = BRUSHSET_ENSURE_BUILTIN(cmd->params, falloff_curve);
BrushChannel *ch2 = BRUSHSET_LOOKUP(chset, autosmooth_falloff_curve);
@ -1569,6 +1607,7 @@ void BKE_builtin_commandlist_create(Brush *brush,
if (!no_rake && topology_rake > 0.0f) {
cmd = BKE_brush_command_init(BKE_brush_commandlist_add(cl, chset, true),
SCULPT_TOOL_TOPOLOGY_RAKE);
BKE_builtin_apply_hard_edge_mode(cmd->params, hard_edge_mode);
BrushChannel *ch = BRUSHSET_ENSURE_BUILTIN(cmd->params, falloff_curve);
BrushChannel *ch2 = BRUSHSET_LOOKUP(chset, topology_rake_falloff_curve);
@ -1591,6 +1630,7 @@ void BKE_builtin_commandlist_create(Brush *brush,
if (!BKE_brush_channelset_get_int(chset, "dyntopo_disabled", NULL)) {
cmd = BKE_brush_command_init(BKE_brush_commandlist_add(cl, chset, true), SCULPT_TOOL_DYNTOPO);
BKE_builtin_apply_hard_edge_mode(cmd->params, hard_edge_mode);
float spacing = BKE_brush_channelset_get_float(chset, "dyntopo_spacing", mapdata);
float radius2 = BKE_brush_channelset_get_float(chset, "dyntopo_radius_scale", mapdata);

View File

@ -736,7 +736,7 @@ void BKE_brush_channelset_compat_load(BrushChannelSet *chset, Brush *brush, bool
}
}
ATTR_NO_OPT static void reset_clay_mappings(BrushChannelSet *chset, bool strips)
static void reset_clay_mappings(BrushChannelSet *chset, bool strips)
{
BrushMapping *mp = BRUSHSET_LOOKUP(chset, radius)->mappings + BRUSH_MAPPING_PRESSURE;
BKE_brush_mapping_ensure_write(mp);
@ -793,11 +793,10 @@ void BKE_brush_builtin_patch(Brush *brush, int tool)
namestack_push(__func__);
bool setup_ui = false;
bool setup_ui = !brush->channels || !brush->channels->totchannel;
if (!brush->channels) {
brush->channels = BKE_brush_channelset_create();
setup_ui = true;
}
BrushChannelSet *chset = brush->channels;
@ -854,6 +853,8 @@ void BKE_brush_builtin_patch(Brush *brush, int tool)
ADDCH(dyntopo_spacing);
ADDCH(dyntopo_radius_scale);
ADDCH(smooth_strength_factor);
ADDCH(accumulate);
ADDCH(original_normal);
ADDCH(original_plane);
@ -990,6 +991,14 @@ void BKE_brush_channelset_ui_init(Brush *brush, int tool)
SHOWALL(color);
SHOWALL(secondary_color);
if (!ELEM(tool,
SCULPT_TOOL_DRAW_FACE_SETS,
SCULPT_TOOL_PAINT,
SCULPT_TOOL_SMEAR,
SCULPT_TOOL_VCOL_BOUNDARY)) {
SHOWALL(hard_edge_mode);
}
if (!ELEM(tool,
SCULPT_TOOL_SNAKE_HOOK,
SCULPT_TOOL_ARRAY,
@ -1402,6 +1411,8 @@ void BKE_brush_check_toolsettings(Sculpt *sd)
ADDCH(radius_unit);
ADDCH(unprojected_radius);
ADDCH(smooth_strength_factor);
ADDCH(tilt_strength_factor);
ADDCH(automasking_boundary_edges_propagation_steps);
ADDCH(concave_mask_factor);

View File

@ -2250,11 +2250,11 @@ void CustomData_copy_all_layout(const struct CustomData *source, struct CustomDa
}
}
ATTR_NO_OPT bool CustomData_merge(const struct CustomData *source,
struct CustomData *dest,
CustomDataMask mask,
eCDAllocType alloctype,
int totelem)
bool CustomData_merge(const struct CustomData *source,
struct CustomData *dest,
CustomDataMask mask,
eCDAllocType alloctype,
int totelem)
{
// const LayerTypeInfo *typeInfo;
CustomDataLayer *layer, *newlayer;
@ -2355,11 +2355,11 @@ void CustomData_realloc(CustomData *data, int totelem)
}
}
ATTR_NO_OPT void CustomData_copy(const struct CustomData *source,
struct CustomData *dest,
CustomDataMask mask,
eCDAllocType alloctype,
int totelem)
void CustomData_copy(const struct CustomData *source,
struct CustomData *dest,
CustomDataMask mask,
eCDAllocType alloctype,
int totelem)
{
CustomData_reset(dest);
@ -3074,7 +3074,7 @@ bool CustomData_is_referenced_layer(struct CustomData *data, int type)
return (layer->flag & CD_FLAG_NOFREE) != 0;
}
ATTR_NO_OPT void CustomData_unmark_temporary_nocopy(CustomData *data)
void CustomData_unmark_temporary_nocopy(CustomData *data)
{
for (int i = 0; i < data->totlayer; i++) {
if (data->layers[i].flag & CD_FLAG_TEMPORARY) {
@ -3083,7 +3083,7 @@ ATTR_NO_OPT void CustomData_unmark_temporary_nocopy(CustomData *data)
}
}
ATTR_NO_OPT void CustomData_mark_temporary_nocopy(CustomData *data)
void CustomData_mark_temporary_nocopy(CustomData *data)
{
for (int i = 0; i < data->totlayer; i++) {
if (data->layers[i].flag & CD_FLAG_TEMPORARY) {
@ -3092,7 +3092,7 @@ ATTR_NO_OPT void CustomData_mark_temporary_nocopy(CustomData *data)
}
}
ATTR_NO_OPT void CustomData_free_temporary(CustomData *data, int totelem)
void CustomData_free_temporary(CustomData *data, int totelem)
{
int i, j;
bool changed = false;

View File

@ -1854,7 +1854,7 @@ BLI_INLINE IDOverrideLibraryRuntime *override_library_rna_path_runtime_ensure(
}
/* We only build override GHash on request. */
ATTR_NO_OPT BLI_INLINE GHash *override_library_rna_path_mapping_ensure(IDOverrideLibrary *override)
BLI_INLINE GHash *override_library_rna_path_mapping_ensure(IDOverrideLibrary *override)
{
IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_runtime_ensure(override);
if (override_runtime->rna_path_to_override_properties == NULL) {

View File

@ -1473,12 +1473,12 @@ int BKE_pbvh_do_fset_symmetry(int fset, const int symflag, const float *co)
return fset;
}
ATTR_NO_OPT void bke_pbvh_update_vert_boundary(int cd_dyn_vert,
int cd_faceset_offset,
int cd_vert_node_offset,
int cd_face_node_offset,
BMVert *v,
int bound_symmetry)
void bke_pbvh_update_vert_boundary(int cd_dyn_vert,
int cd_faceset_offset,
int cd_vert_node_offset,
int cd_face_node_offset,
BMVert *v,
int bound_symmetry)
{
MDynTopoVert *mv = BKE_PBVH_DYNVERT(cd_dyn_vert, v);

View File

@ -4425,7 +4425,7 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
ToolSettings *ts = scene->toolsettings;
UnifiedPaintSettings *ups = &ts->unified_paint_settings;
ups->flag &= ~(UNIFIED_PAINT_FLAG_UNUSED_1);
ups->flag &= ~(UNIFIED_PAINT_FLAG_UI_ADVANCED);
}
/* Set the default render pass in the viewport to Combined. */

View File

@ -128,7 +128,7 @@ void bm_id_freelist_push(BMesh *bm, uint id)
// static const int _typemap[] = {0, 0, 1, 0, 2, 0, 0, 0, 3};
ATTR_NO_OPT void bm_assign_id_intern(BMesh *bm, BMElem *elem, uint id)
void bm_assign_id_intern(BMesh *bm, BMElem *elem, uint id)
{
// CustomData *cdata = &bm->vdata + _typemap[elem->head.htype];
// int cd_id_off = cdata->layers[cdata->typemap[CD_MESH_ID]].offset;
@ -163,7 +163,7 @@ ATTR_NO_OPT void bm_assign_id_intern(BMesh *bm, BMElem *elem, uint id)
}
}
ATTR_NO_OPT void bm_assign_id(BMesh *bm, BMElem *elem, uint id, bool check_unqiue)
void bm_assign_id(BMesh *bm, BMElem *elem, uint id, bool check_unqiue)
{
if (check_unqiue && (bm->idmap.flag & BM_HAS_ID_MAP)) {
if (BM_ELEM_FROM_ID(bm, id)) {

View File

@ -1370,10 +1370,7 @@ static void update_data_blocks(BMesh *bm, CustomData *olddata, CustomData *data)
}
}
ATTR_NO_OPT void BM_data_layers_ensure(BMesh *bm,
CustomData *data,
BMCustomLayerReq *layers,
int totlayer)
void BM_data_layers_ensure(BMesh *bm, CustomData *data, BMCustomLayerReq *layers, int totlayer)
{
bool modified = false;
CustomData old = *data;

View File

@ -1425,7 +1425,7 @@ BMLog *BM_log_unfreeze(BMesh *bm, BMLogEntry *entry)
/* Free all the data in a BMLog including the log itself
* safe_mode means log->refcount will be checked, and if nonzero log will not be freed
*/
ATTR_NO_OPT static bool bm_log_free_direct(BMLog *log, bool safe_mode)
static bool bm_log_free_direct(BMLog *log, bool safe_mode)
{
BMLogEntry *entry;

View File

@ -916,7 +916,7 @@ BLI_INLINE void bmesh_quick_edgedraw_flag(MEdge *med, BMEdge *e)
* \param bmain: May be NULL in case \a calc_object_remap parameter option is not set.
*/
ATTR_NO_OPT void BM_mesh_bm_to_me(
void BM_mesh_bm_to_me(
Main *bmain, Object *ob, BMesh *bm, Mesh *me, const struct BMeshToMeshParams *params)
{
MEdge *med;

View File

@ -467,13 +467,13 @@ void SCULPT_vertex_persistent_normal_get(SculptSession *ss, SculptVertRef vertex
}
}
ATTR_NO_OPT static bool sculpt_temp_customlayer_get(SculptSession *ss,
AttributeDomain domain,
int proptype,
char *name,
SculptCustomLayer *out,
bool autocreate,
SculptLayerParams *params)
static bool sculpt_temp_customlayer_get(SculptSession *ss,
AttributeDomain domain,
int proptype,
char *name,
SculptCustomLayer *out,
bool autocreate,
SculptLayerParams *params)
{
bool simple_array = params->simple_array;
bool permanent = params->permanent;
@ -732,7 +732,7 @@ ATTR_NO_OPT static bool sculpt_temp_customlayer_get(SculptSession *ss,
return true;
}
ATTR_NO_OPT void SCULPT_update_customdata_refs(SculptSession *ss)
void SCULPT_update_customdata_refs(SculptSession *ss)
{
if (ss->bm) {
SCULPT_dyntopo_node_layers_update_offsets(ss);
@ -3892,9 +3892,9 @@ static float brush_strength(const Sculpt *sd,
case SCULPT_TOOL_SMOOTH: {
const float smooth_strength_base = flip * pressure * feather;
if (cache->alt_smooth) {
return smooth_strength_base * sd->smooth_strength_factor;
}
// if (cache->alt_smooth) {
// return smooth_strength_base * sd->smooth_strength_factor;
//}
return smooth_strength_base * alpha;
}
@ -6796,9 +6796,9 @@ static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
//#define LAYER_FACE_SET_MODE
ATTR_NO_OPT static void do_layer_brush_task_cb_ex(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict tls)
static void do_layer_brush_task_cb_ex(void *__restrict userdata,
const int n,
const TaskParallelTLS *__restrict tls)
{
SculptThreadedTaskData *data = userdata;
SculptSession *ss = data->ob->sculpt;
@ -8649,6 +8649,7 @@ void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings
case SCULPT_TOOL_LAYER:
case SCULPT_TOOL_DRAW_FACE_SETS:
case SCULPT_TOOL_CLOTH:
case SCULPT_TOOL_SMOOTH:
case SCULPT_TOOL_SIMPLIFY:
case SCULPT_TOOL_SNAKE_HOOK:
case SCULPT_TOOL_INFLATE:
@ -8666,6 +8667,11 @@ void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings
BrushCommandList *list = ss->cache->commandlist = BKE_brush_commandlist_create();
if (ss->cache->alt_smooth && brush->sculpt_tool == SCULPT_TOOL_SMOOTH) {
float factor = BRUSHSET_GET_FLOAT(ss->cache->channels_final, smooth_strength_factor, NULL);
BRUSHSET_SET_FLOAT(ss->cache->channels_final, strength, factor);
}
BKE_builtin_commandlist_create(
brush, ss->cache->channels_final, list, brush->sculpt_tool, &ss->cache->input_mapping);
}
@ -11605,6 +11611,23 @@ void sculpt_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerR
ss->cache->channels_final = BKE_brush_channelset_copy(brush->channels);
}
if (ss->cache->alt_smooth) {
Brush *brush = (Brush *)BKE_libblock_find_name(
CTX_data_main(C), ID_BR, ss->cache->saved_active_brush_name);
if (brush) {
// some settings should not be overridden
bool hard_edge = BRUSHSET_GET_FINAL_INT(
brush->channels, sd->channels ? sd->channels : NULL, hard_edge_mode, NULL);
float smooth_factor = BRUSHSET_GET_FINAL_FLOAT(
brush->channels, sd->channels ? sd->channels : NULL, smooth_strength_factor, NULL);
BRUSHSET_SET_INT(ss->cache->channels_final, hard_edge_mode, hard_edge);
BRUSHSET_SET_FLOAT(ss->cache->channels_final, smooth_strength_factor, smooth_factor);
}
}
// load settings into brush and unified paint settings
BKE_brush_channelset_compat_load(ss->cache->channels_final, brush, false);
BKE_brush_channelset_to_unified_settings(ss->cache->channels_final, ups);
@ -11939,7 +11962,7 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
/* Reset the copy of the mesh that is being sculpted on (currently just for the layer brush). */
ATTR_NO_OPT static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op))
static int sculpt_set_persistent_base_exec(bContext *C, wmOperator *UNUSED(op))
{
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
Object *ob = CTX_data_active_object(C);

View File

@ -478,7 +478,7 @@ AutomaskingCache *SCULPT_automasking_cache_init(Sculpt *sd, const Brush *brush,
SCULPT_face_random_access_ensure(ss);
automasking->factorlayer = MEM_callocN(sizeof(SculptCustomLayer), "automasking->factorlayer");
SculptLayerParams params = {.permanent = false, .simple_array = true};
SculptLayerParams params = {.permanent = false, .simple_array = false};
if (!SCULPT_temp_customlayer_get(ss,
ATTR_DOMAIN_POINT,

View File

@ -484,7 +484,7 @@ typedef struct ImageFormatData {
#define R_IMF_IMTYPE_INVALID 255
/** #ImageFormatData.flag */
#define R_IMF_FLAG_ZBUF (1 << 0) /* was R_OPENEXR_ZBUF */
#define R_IMF_FLAG_ZBUF (1 << 0) /* was R_OPENEXR_ZBUF */
#define R_IMF_FLAG_PREVIEW_JPG (1 << 1) /* was R_PREVIEW_JPG */
/* Return values from #BKE_imtype_valid_depths, note this is depths per channel. */
@ -526,8 +526,8 @@ typedef enum eImageFormatDepth {
/** #ImageFormatData.jp2_flag */
#define R_IMF_JP2_FLAG_YCC (1 << 0) /* when disabled use RGB */ /* was R_JPEG2K_YCC */
#define R_IMF_JP2_FLAG_CINE_PRESET (1 << 1) /* was R_JPEG2K_CINE_PRESET */
#define R_IMF_JP2_FLAG_CINE_48 (1 << 2) /* was R_JPEG2K_CINE_48FPS */
#define R_IMF_JP2_FLAG_CINE_PRESET (1 << 1) /* was R_JPEG2K_CINE_PRESET */
#define R_IMF_JP2_FLAG_CINE_48 (1 << 2) /* was R_JPEG2K_CINE_48FPS */
/** #ImageFormatData.jp2_codec */
#define R_IMF_JP2_CODEC_JP2 0
@ -1282,7 +1282,7 @@ typedef enum {
UNIFIED_PAINT_BRUSH_LOCK_SIZE = (1 << 2),
UNIFIED_PAINT_FLAG_HARD_EDGE_MODE = (1 << 3),
UNIFIED_PAINT_FLAG_UNUSED_1 = (1 << 4),
UNIFIED_PAINT_FLAG_UI_ADVANCED = (1 << 4),
} eUnifiedPaintSettingsFlags;
typedef struct CurvePaintSettings {
@ -1863,12 +1863,12 @@ typedef struct Scene {
#define R_MODE_UNUSED_20 (1 << 20) /* cleared */
#define R_MODE_UNUSED_21 (1 << 21) /* cleared */
#define R_NO_OVERWRITE (1 << 22) /* skip existing files */
#define R_TOUCH (1 << 23) /* touch files before rendering */
#define R_NO_OVERWRITE (1 << 22) /* skip existing files */
#define R_TOUCH (1 << 23) /* touch files before rendering */
#define R_SIMPLIFY (1 << 24)
#define R_EDGE_FRS (1 << 25) /* R_EDGE reserved for Freestyle */
#define R_EDGE_FRS (1 << 25) /* R_EDGE reserved for Freestyle */
#define R_PERSISTENT_DATA (1 << 26) /* keep data around for re-render */
#define R_MODE_UNUSED_27 (1 << 27) /* cleared */
#define R_MODE_UNUSED_27 (1 << 27) /* cleared */
/** #RenderData.seq_flag */
enum {

View File

@ -330,15 +330,15 @@ bool RNA_struct_equals(Main *bmain, PointerRNA *ptr_a, PointerRNA *ptr_b, eRNACo
* \note When there is no equality,
* but we cannot determine an order (greater than/lesser than), we return 1.
*/
ATTR_NO_OPT static int rna_property_override_diff(Main *bmain,
PropertyRNAOrID *prop_a,
PropertyRNAOrID *prop_b,
const char *rna_path,
const size_t rna_path_len,
eRNACompareMode mode,
IDOverrideLibrary *override,
const eRNAOverrideMatch flags,
eRNAOverrideMatchResult *r_report_flags)
static int rna_property_override_diff(Main *bmain,
PropertyRNAOrID *prop_a,
PropertyRNAOrID *prop_b,
const char *rna_path,
const size_t rna_path_len,
eRNACompareMode mode,
IDOverrideLibrary *override,
const eRNAOverrideMatch flags,
eRNAOverrideMatchResult *r_report_flags)
{
BLI_assert(!ELEM(NULL, prop_a, prop_b));
@ -641,14 +641,14 @@ static bool rna_property_override_operation_apply(Main *bmain,
* \return True if _resulting_ \a ptr_local does match \a ptr_reference.
*/
#include "stdio.h"
ATTR_NO_OPT bool RNA_struct_override_matches(Main *bmain,
PointerRNA *ptr_local,
PointerRNA *ptr_reference,
const char *root_path,
const size_t root_path_len,
IDOverrideLibrary *override,
const eRNAOverrideMatch flags,
eRNAOverrideMatchResult *r_report_flags)
bool RNA_struct_override_matches(Main *bmain,
PointerRNA *ptr_local,
PointerRNA *ptr_reference,
const char *root_path,
const size_t root_path_len,
IDOverrideLibrary *override,
const eRNAOverrideMatch flags,
eRNAOverrideMatchResult *r_report_flags)
{
CollectionPropertyIterator iter;
PropertyRNA *iterprop;

View File

@ -144,7 +144,6 @@ const EnumPropertyItem rna_enum_brush_sculpt_tool_items[] = {
{SCULPT_TOOL_DRAW_FACE_SETS, "DRAW_FACE_SETS", ICON_BRUSH_MASK, "Draw Face Sets", ""},
{SCULPT_TOOL_SYMMETRIZE, "SYMMETRIZE", ICON_BRUSH_SCULPT_DRAW, "Symmetrize", ""},
{SCULPT_TOOL_ARRAY, "ARRAY", ICON_BRUSH_SCULPT_DRAW, "Array", ""},
{0, NULL, 0, NULL, NULL},
{SCULPT_TOOL_VCOL_BOUNDARY, "VCOL_BOUNDARY", ICON_BRUSH_VCOL_BOUNDARY, "Sharpen Color Boundary", ""},
{SCULPT_TOOL_UV_SMOOTH, "UV_SMOOTH", ICON_BRUSH_GRAB, "UV Smooth", ""},
{0, NULL, 0, NULL, NULL},

View File

@ -78,8 +78,7 @@ BrushChannelSet *rna_BrushChannelSet_get_set(struct PointerRNA *ptr)
return chset;
}
ATTR_NO_OPT int rna_BrushChannelSet_channels_begin(CollectionPropertyIterator *iter,
struct PointerRNA *ptr)
int rna_BrushChannelSet_channels_begin(CollectionPropertyIterator *iter, struct PointerRNA *ptr)
{
BrushChannelSet *chset = rna_BrushChannelSet_get_set(ptr);
@ -421,7 +420,7 @@ char *rna_BrushChannel_rnapath(PointerRNA *ptr)
}
}
ATTR_NO_OPT void rna_BrushChannelSet_ensure(ID *id, BrushChannel *channel)
void rna_BrushChannelSet_ensure(ID *id, BrushChannel *channel)
{
PointerRNA ptr;
@ -435,7 +434,7 @@ ATTR_NO_OPT void rna_BrushChannelSet_ensure(ID *id, BrushChannel *channel)
}
}
ATTR_NO_OPT int rna_BrushChannelSet_length(PointerRNA *ptr)
int rna_BrushChannelSet_length(PointerRNA *ptr)
{
BrushChannelSet *chset = rna_BrushChannelSet_get_set(ptr);
// BrushChannelSet *chset = (BrushChannelSet *)ptr->data;

View File

@ -1488,15 +1488,15 @@ static int rna_property_override_diff_propptr(Main *bmain,
(is_array ? RNA_property_##_typename##_set_index((_ptr), (_prop), (_index), (_value)) : \
RNA_property_##_typename##_set((_ptr), (_prop), (_value)))
ATTR_NO_OPT int rna_property_override_diff_default(Main *bmain,
PropertyRNAOrID *prop_a,
PropertyRNAOrID *prop_b,
const int mode,
IDOverrideLibrary *override,
const char *rna_path,
const size_t rna_path_len,
const int flags,
bool *r_override_changed)
int rna_property_override_diff_default(Main *bmain,
PropertyRNAOrID *prop_a,
PropertyRNAOrID *prop_b,
const int mode,
IDOverrideLibrary *override,
const char *rna_path,
const size_t rna_path_len,
const int flags,
bool *r_override_changed)
{
PointerRNA *ptr_a = &prop_a->ptr;
PointerRNA *ptr_b = &prop_b->ptr;

View File

@ -3682,6 +3682,16 @@ static void rna_def_unified_paint_settings(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Hard Edge Mode", "Hard edge mode; treat all face set boundaries as hard edges");
RNA_def_property_update(prop, 0, "rna_UnifiedPaintSettings_update");
prop = RNA_def_property(srna, "brush_editor_mode", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", UNIFIED_PAINT_FLAG_UI_ADVANCED);
RNA_def_property_ui_text(prop, "Workspace Edit Mode", "Brush editor mode");
RNA_def_property_update(prop, NC_BRUSH | NA_EDITED, NULL);
prop = RNA_def_property(srna, "brush_editor_advanced", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", 1 << 7);
RNA_def_property_ui_text(prop, "Show Advanced", "Show Advanced Settings");
RNA_def_property_update(prop, NC_BRUSH | NA_EDITED, NULL);
}
static void rna_def_curve_paint_settings(BlenderRNA *brna)

View File

@ -606,7 +606,7 @@ static char *rna_GPencilSculptGuide_path(PointerRNA *UNUSED(ptr))
bool SCULPT_has_persistent_base(SculptSession *ss);
ATTR_NO_OPT bool rna_Sculpt_has_persistent_base(bContext *C)
bool rna_Sculpt_has_persistent_base(bContext *C)
{
ePaintMode mode = BKE_paintmode_get_active_from_context(C);