UI: Gray out Scene Auto-Masking option if equivalent Brush option is used #102971 #106126
|
@ -7854,42 +7854,63 @@ class VIEW3D_PT_sculpt_automasking(Panel):
|
|||
layout = self.layout
|
||||
|
||||
tool_settings = context.tool_settings
|
||||
brush = tool_settings.sculpt.brush
|
||||
sculpt = tool_settings.sculpt
|
||||
layout.label(text="Auto-Masking")
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.prop(sculpt, "use_automasking_topology", text="Topology")
|
||||
col.prop(sculpt, "use_automasking_face_sets", text="Face Sets")
|
||||
sub = col.column()
|
||||
sub.active = not brush.use_automasking_topology
|
||||
sub.prop(sculpt, "use_automasking_topology", text="Topology")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = not brush.use_automasking_face_sets
|
||||
sub.prop(sculpt, "use_automasking_face_sets", text="Face Sets")
|
||||
|
||||
col.separator()
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.prop(sculpt, "use_automasking_boundary_edges", text="Mesh Boundary")
|
||||
col.prop(sculpt, "use_automasking_boundary_face_sets", text="Face Sets Boundary")
|
||||
sub = col.column()
|
||||
sub.active = not brush.use_automasking_boundary_edges
|
||||
sub.prop(sculpt, "use_automasking_boundary_edges", text="Mesh Boundary")
|
||||
|
||||
sub = col.column()
|
||||
sub.active = not brush.use_automasking_boundary_face_sets
|
||||
sub.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")
|
||||
sub = col.column()
|
||||
sub.active = not brush.use_automasking_boundary_edges or not brush.use_automasking_boundary_face_sets
|
||||
sub.prop(sculpt.brush, "automasking_boundary_edges_propagation_steps")
|
||||
|
||||
col.separator()
|
||||
|
||||
col = layout.column(align=True)
|
||||
row = col.row()
|
||||
row.prop(sculpt, "use_automasking_cavity", text="Cavity")
|
||||
subrow = row.column(align=True)
|
||||
subrow.active = not brush.use_automasking_cavity and not brush.use_automasking_cavity_inverted
|
||||
subrow.prop(sculpt, "use_automasking_cavity", text="Cavity")
|
||||
|
||||
is_cavity_active = sculpt.use_automasking_cavity or sculpt.use_automasking_cavity_inverted
|
||||
|
||||
if is_cavity_active:
|
||||
props = row.operator("sculpt.mask_from_cavity", text="Create Mask")
|
||||
subrow = row.column(align=True)
|
||||
subrow.enabled = not brush.use_automasking_cavity and not brush.use_automasking_cavity_inverted
|
||||
props = subrow.operator("sculpt.scene_mask_from_cavity", text="Create Mask")
|
||||
props.settings_source = "SCENE"
|
||||
|
||||
col.prop(sculpt, "use_automasking_cavity_inverted", text="Cavity (inverted)")
|
||||
subcol = col.column(align=True)
|
||||
subcol.active = not brush.use_automasking_cavity and not brush.use_automasking_cavity_inverted
|
||||
subcol.prop(sculpt, "use_automasking_cavity_inverted", text="Cavity (inverted)")
|
||||
|
||||
if is_cavity_active:
|
||||
col = layout.column(align=True)
|
||||
col.active = not brush.use_automasking_cavity_inverted and not brush.use_automasking_cavity
|
||||
col.prop(sculpt, "automasking_cavity_factor", text="Factor")
|
||||
col.prop(sculpt, "automasking_cavity_blur_steps", text="Blur")
|
||||
|
||||
col = layout.column()
|
||||
col.active = not brush.use_automasking_cavity_inverted and not brush.use_automasking_cavity
|
||||
col.prop(sculpt, "use_automasking_custom_cavity_curve", text="Custom Curve")
|
||||
|
||||
if sculpt.use_automasking_custom_cavity_curve:
|
||||
|
@ -7898,20 +7919,23 @@ class VIEW3D_PT_sculpt_automasking(Panel):
|
|||
col.separator()
|
||||
|
||||
col = layout.column(align=True)
|
||||
col.active = not brush.use_automasking_view_normal
|
||||
col.prop(sculpt, "use_automasking_view_normal", text="View Normal")
|
||||
|
||||
if sculpt.use_automasking_view_normal:
|
||||
col.prop(sculpt, "use_automasking_view_occlusion", text="Occlusion")
|
||||
subcol = col.column(align=True)
|
||||
subcol.active = not sculpt.use_automasking_view_occlusion
|
||||
subcol.prop(sculpt, "automasking_view_normal_limit", text="Limit")
|
||||
subcol.prop(sculpt, "automasking_view_normal_falloff", text="Falloff")
|
||||
subcol.prop(sculpt, "automasking_scene_view_normal_limit", text="Limit")
|
||||
subcol.prop(sculpt, "automasking_scene_view_normal_falloff", text="Falloff")
|
||||
|
||||
col = layout.column()
|
||||
col.active = not brush.use_automasking_start_normal
|
||||
col.prop(sculpt, "use_automasking_start_normal", text="Area Normal")
|
||||
|
||||
if sculpt.use_automasking_start_normal:
|
||||
col = layout.column(align=True)
|
||||
col.active = not brush.use_automasking_start_normal
|
||||
col.prop(sculpt, "automasking_start_normal_limit", text="Limit")
|
||||
col.prop(sculpt, "automasking_start_normal_falloff", text="Falloff")
|
||||
|
||||
|
|
|
@ -2078,6 +2078,8 @@ void BKE_sculpt_toolsettings_data_ensure(Scene *scene)
|
|||
sd->automasking_start_normal_limit = 20.0f / 180.0f * M_PI;
|
||||
sd->automasking_start_normal_falloff = 0.25f;
|
||||
|
||||
sd->automasking_scene_view_normal_limit = 90.0f / 180.0f * M_PI;
|
||||
|
||||
sd->automasking_scene_view_normal_falloff = 0.25f;
|
||||
sd->automasking_view_normal_limit = 90.0f / 180.0f * M_PI;
|
||||
sd->automasking_view_normal_falloff = 0.25f;
|
||||
}
|
||||
|
|
|
@ -896,6 +896,7 @@ void UI_but_dragflag_enable(uiBut *but, int flag);
|
|||
void UI_but_dragflag_disable(uiBut *but, int flag);
|
||||
|
||||
void UI_but_disable(uiBut *but, const char *disabled_hint);
|
||||
void UI_but_set_disabled_hint(uiBut *but, const char *disabled_hint);
|
||||
|
||||
void UI_but_type_set_menu_from_pulldown(uiBut *but);
|
||||
|
||||
|
|
|
@ -4715,6 +4715,10 @@ static uiBut *ui_def_but_rna(uiBlock *block,
|
|||
UI_but_disable(but, info);
|
||||
}
|
||||
|
||||
if (but->rnapoin.data && RNA_property_is_inactive_info(&but->rnapoin, prop, &info)) {
|
||||
UI_but_set_disabled_hint(but, info);
|
||||
}
|
||||
|
||||
if (proptype == PROP_POINTER) {
|
||||
/* If the button shows an ID, automatically set it as focused in context so operators can
|
||||
* access it. */
|
||||
|
@ -5904,10 +5908,8 @@ void UI_but_dragflag_disable(uiBut *but, int flag)
|
|||
but->dragflag &= ~flag;
|
||||
}
|
||||
|
||||
void UI_but_disable(uiBut *but, const char *disabled_hint)
|
||||
void UI_but_set_disabled_hint(uiBut *but, const char *disabled_hint)
|
||||
{
|
||||
UI_but_flag_enable(but, UI_BUT_DISABLED);
|
||||
|
||||
/* Only one disabled hint at a time currently. Don't override the previous one here. */
|
||||
if (but->disabled_info && but->disabled_info[0]) {
|
||||
return;
|
||||
|
@ -5916,6 +5918,13 @@ void UI_but_disable(uiBut *but, const char *disabled_hint)
|
|||
but->disabled_info = disabled_hint;
|
||||
}
|
||||
|
||||
void UI_but_disable(uiBut *but, const char *disabled_hint)
|
||||
{
|
||||
UI_but_flag_enable(but, UI_BUT_DISABLED);
|
||||
|
||||
UI_but_set_disabled_hint(but, disabled_hint);
|
||||
}
|
||||
|
||||
void UI_but_type_set_menu_from_pulldown(uiBut *but)
|
||||
{
|
||||
BLI_assert(but->type == UI_BTYPE_PULLDOWN);
|
||||
|
|
|
@ -897,8 +897,8 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C,
|
|||
MEM_freeN(str);
|
||||
}
|
||||
|
||||
/* Button is disabled, we may be able to tell user why. */
|
||||
if ((but->flag & UI_BUT_DISABLED) || extra_icon) {
|
||||
/* Button is disabled or set to inactive, we may be able to tell user why. */
|
||||
if ((but->flag & UI_BUT_DISABLED) || (but->flag & UI_BUT_INACTIVE) || extra_icon) {
|
||||
Julian Eisel
commented
Can be shortened:
Can be shortened:
```C
if ((but->flag & (UI_BUT_DISABLED | UI_BUT_INACTIVE)) || extra_icon) {
...
}
```
Henry-Chang
commented
Understood, would update. Understood, would update.
|
||||
const char *disabled_msg = nullptr;
|
||||
bool disabled_msg_free = false;
|
||||
|
||||
|
|
|
@ -4273,6 +4273,19 @@ bool SCULPT_mode_poll(bContext *C)
|
|||
return ob && ob->mode & OB_MODE_SCULPT;
|
||||
}
|
||||
|
||||
bool SCULPT_mode_poll_cavity_automask(bContext *C)
|
||||
{
|
||||
ToolSettings *tool_settings = CTX_data_tool_settings(C);
|
||||
int automasking_flags = tool_settings->sculpt->paint.brush->automasking_flags;
|
||||
|
||||
if (SCULPT_mode_poll(C) && !(automasking_flags & BRUSH_AUTOMASKING_CAVITY_ALL)) {
|
||||
Julian Eisel
commented
I find it generally more readable if error conditions are checked individually first. I.e.:
This minimizes the amount of information you have to keep in mind or understand when reading/changing code. (Also this would set the wrong poll message outside of sculpt mode, one more reason to keep error condition checks separate.) I find it generally more readable if error conditions are checked individually first. I.e.:
```C
if (!SCULPT_mode_poll(C) {
return false;
}
if (automasking_flags & BRUSH_AUTOMASKING_CAVITY_ALL) {
CTX_wm_operator_poll_msg_set(C, ...);
return false
}
return true;
```
This minimizes the amount of information you have to keep in mind or understand when reading/changing code. (Also this would set the wrong poll message outside of sculpt mode, one more reason to keep error condition checks separate.)
Henry-Chang
commented
Makes sense, would update. Makes sense, would update.
|
||||
return true;
|
||||
} else {
|
||||
CTX_wm_operator_poll_msg_set(C, "The active brush already has the same auto-masking enabled.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool SCULPT_mode_poll_view3d(bContext *C)
|
||||
{
|
||||
return (SCULPT_mode_poll(C) && CTX_wm_region_view3d(C));
|
||||
|
|
|
@ -843,6 +843,7 @@ struct ExpandCache {
|
|||
* \{ */
|
||||
|
||||
bool SCULPT_mode_poll(bContext *C);
|
||||
bool SCULPT_mode_poll_cavity_automask(bContext *C);
|
||||
bool SCULPT_mode_poll_view3d(bContext *C);
|
||||
/**
|
||||
* Checks for a brush, not just sculpt mode.
|
||||
|
|
|
@ -1290,6 +1290,13 @@ static void SCULPT_OT_mask_from_cavity(wmOperatorType *ot)
|
|||
RNA_def_boolean(ot->srna, "invert", false, "Cavity (Inverted)", "");
|
||||
}
|
||||
|
||||
static void SCULPT_OT_scene_mask_from_cavity(wmOperatorType *ot)
|
||||
{
|
||||
SCULPT_OT_mask_from_cavity(ot);
|
||||
ot->idname = "SCULPT_OT_scene_mask_from_cavity";
|
||||
ot->poll = SCULPT_mode_poll_cavity_automask;
|
||||
}
|
||||
|
||||
static int sculpt_reveal_all_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
|
@ -1424,6 +1431,7 @@ void ED_operatortypes_sculpt(void)
|
|||
WM_operatortype_append(SCULPT_OT_mask_init);
|
||||
|
||||
WM_operatortype_append(SCULPT_OT_expand);
|
||||
WM_operatortype_append(SCULPT_OT_scene_mask_from_cavity);
|
||||
WM_operatortype_append(SCULPT_OT_mask_from_cavity);
|
||||
WM_operatortype_append(SCULPT_OT_reveal_all);
|
||||
}
|
||||
|
|
|
@ -1089,6 +1089,7 @@ typedef struct Sculpt {
|
|||
|
||||
float automasking_start_normal_limit, automasking_start_normal_falloff;
|
||||
float automasking_view_normal_limit, automasking_view_normal_falloff;
|
||||
float automasking_scene_view_normal_limit, automasking_scene_view_normal_falloff;
|
||||
|
||||
struct CurveMapping *automasking_cavity_curve;
|
||||
/** For use by operators. */
|
||||
|
|
|
@ -274,6 +274,7 @@ bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop);
|
|||
* that can be exposed in UI.
|
||||
*/
|
||||
bool RNA_property_editable_info(PointerRNA *ptr, PropertyRNA *prop, const char **r_info);
|
||||
bool RNA_property_is_inactive_info(PointerRNA *ptr, PropertyRNA *prop, const char **r_info);
|
||||
/**
|
||||
* Same as RNA_property_editable(), except this checks individual items in an array.
|
||||
*/
|
||||
|
|
|
@ -187,6 +187,15 @@ typedef enum PropertyFlag {
|
|||
* for pointers and collections.
|
||||
*/
|
||||
PROP_EDITABLE = (1 << 0),
|
||||
/**
|
||||
* Inactive specifically only refers to the front end
|
||||
* where UI elements are grayed out but can still be
|
||||
* toggled. It is specifically used to add Disabled
|
||||
* message for when UI is set to inactive through Python
|
||||
* script. It is completely unrelated to anything that
|
||||
* is performed in the backend.
|
||||
*/
|
||||
PROP_INACTIVE = (1 << 9),
|
||||
/**
|
||||
* This property is editable even if it is lib linked,
|
||||
* meaning it will get lost on reload, but it's useful
|
||||
|
|
|
@ -1935,6 +1935,32 @@ int RNA_property_ui_icon(const PropertyRNA *prop)
|
|||
return rna_ensure_property((PropertyRNA *)prop)->icon;
|
||||
}
|
||||
|
||||
static bool rna_property_is_inactive_do(PointerRNA *ptr,
|
||||
PropertyRNA *prop_orig,
|
||||
const int index,
|
||||
const char **r_info)
|
||||
{
|
||||
PropertyRNA *prop = rna_ensure_property(prop_orig);
|
||||
|
||||
const char *info = "";
|
||||
const int flag = (prop->itemeditable != nullptr && index >= 0) ?
|
||||
prop->itemeditable(ptr, index) :
|
||||
(prop->editable != nullptr ? prop->editable(ptr, &info) : prop->flag);
|
||||
if (r_info != nullptr) {
|
||||
*r_info = info;
|
||||
}
|
||||
|
||||
/* Return true if the property itself is inative. */
|
||||
if ((flag & PROP_INACTIVE) != 0) {
|
||||
if (r_info != nullptr && (*r_info)[0] == '\0') {
|
||||
*r_info = N_("This property is for internal use only and can't be edited");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool rna_property_editable_do(PointerRNA *ptr,
|
||||
PropertyRNA *prop_orig,
|
||||
const int index,
|
||||
|
@ -2001,6 +2027,11 @@ bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop)
|
|||
return rna_property_editable_do(ptr, prop, -1, nullptr);
|
||||
}
|
||||
|
||||
bool RNA_property_is_inactive_info(PointerRNA *ptr, PropertyRNA *prop, const char **r_info)
|
||||
{
|
||||
return rna_property_is_inactive_do(ptr, prop, -1, r_info);
|
||||
}
|
||||
|
||||
bool RNA_property_editable_info(PointerRNA *ptr, PropertyRNA *prop, const char **r_info)
|
||||
{
|
||||
return rna_property_editable_do(ptr, prop, -1, r_info);
|
||||
|
|
|
@ -3078,6 +3078,7 @@ static void rna_def_brush(BlenderRNA *brna)
|
|||
"Propagation Steps",
|
||||
"Distance where boundary edge automasking is going to protect vertices "
|
||||
"from the fully masked edge");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_mesh_and_face_sets_boundary_editable");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "auto_smooth_factor", PROP_FLOAT, PROP_FACTOR);
|
||||
|
@ -3839,3 +3840,13 @@ void RNA_def_brush(BlenderRNA *brna)
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int rna_Scene_automasking_mesh_and_face_sets_boundary_editable(struct PointerRNA *ptr, const char **r_info) {
|
||||
Brush *br = (Brush*)ptr->data;
|
||||
if (br && (br->automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_EDGES) && (br->automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS)) {
|
||||
*r_info = "The active brush already has the same auto-masking enabled.";
|
||||
return PROP_INACTIVE | PROP_EDITABLE;
|
||||
}
|
||||
|
||||
return br ? PROP_EDITABLE: 0;
|
||||
}
|
||||
|
|
|
@ -862,25 +862,54 @@ static void rna_def_sculpt(BlenderRNA *brna)
|
|||
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Sculpt_update");
|
||||
|
||||
const EnumPropertyItem *entry = rna_enum_brush_automasking_flag_items;
|
||||
do {
|
||||
prop = RNA_def_property(srna, entry->identifier, PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", entry->value);
|
||||
RNA_def_property_ui_text(prop, entry->name, entry->description);
|
||||
prop = RNA_def_property(srna, "use_automasking_topology", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_TOPOLOGY);
|
||||
RNA_def_property_ui_text(prop, "Topology", "Affect only vertices connected to the active vertex under the brush");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_topology_editable");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
if (entry->value == BRUSH_AUTOMASKING_CAVITY_NORMAL) {
|
||||
RNA_def_property_boolean_funcs(prop, NULL, "rna_Sculpt_automasking_cavity_set");
|
||||
}
|
||||
else if (entry->value == BRUSH_AUTOMASKING_CAVITY_INVERTED) {
|
||||
RNA_def_property_boolean_funcs(prop, NULL, "rna_Sculpt_automasking_invert_cavity_set");
|
||||
}
|
||||
prop = RNA_def_property(srna, "use_automasking_face_sets", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_FACE_SETS);
|
||||
RNA_def_property_ui_text(prop, "Face Sets", "Affect only vertices that share Face Sets with the active vertex");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_face_sets_editable");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
} while ((++entry)->identifier);
|
||||
prop = RNA_def_property(srna, "use_automasking_boundary_edges", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_BOUNDARY_EDGES);
|
||||
RNA_def_property_ui_text(prop, "Mesh Boundary Auto-Masking", "Do not affect non manifold boundary edges");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_mesh_boundary_editable");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_automasking_boundary_face_sets", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS);
|
||||
RNA_def_property_ui_text(prop, "Face Sets Boundary Automasking", "Do not affect vertices that belong to a Face Set boundary");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_face_sets_boundary_editable");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_automasking_cavity", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_CAVITY_NORMAL);
|
||||
RNA_def_property_ui_text(prop, "Cavity Mask", "Do not affect vertices on peaks, based on the surface curvature");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_cavity_editable");
|
||||
RNA_def_property_boolean_funcs(prop, NULL, "rna_Sculpt_automasking_cavity_set");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_automasking_cavity_inverted", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_CAVITY_INVERTED);
|
||||
RNA_def_property_ui_text(prop, "Inverted Cavity Mask", "Do not affect vertices within crevices, based on the surface curvature");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_cavity_editable");
|
||||
RNA_def_property_boolean_funcs(prop, NULL, "rna_Sculpt_automasking_invert_cavity_set");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_automasking_custom_cavity_curve", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_CAVITY_USE_CURVE);
|
||||
RNA_def_property_ui_text(prop, "Custom Cavity Curve", "Use custom curve");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_cavity_editable");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "automasking_cavity_factor", PROP_FLOAT, PROP_FACTOR);
|
||||
RNA_def_property_float_sdna(prop, NULL, "automasking_cavity_factor");
|
||||
RNA_def_property_ui_text(prop, "Cavity Factor", "The contrast of the cavity mask");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_cavity_editable");
|
||||
RNA_def_property_float_default(prop, 1.0f);
|
||||
RNA_def_property_range(prop, 0.0f, 5.0f);
|
||||
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
|
||||
|
@ -889,6 +918,7 @@ static void rna_def_sculpt(BlenderRNA *brna)
|
|||
prop = RNA_def_property(srna, "automasking_cavity_blur_steps", PROP_INT, PROP_NONE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "automasking_cavity_blur_steps");
|
||||
RNA_def_property_ui_text(prop, "Blur Steps", "The number of times the cavity mask is blurred");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_cavity_editable");
|
||||
RNA_def_property_int_default(prop, 0);
|
||||
RNA_def_property_range(prop, 0, 25);
|
||||
RNA_def_property_ui_range(prop, 0, 10, 1, 1);
|
||||
|
@ -898,6 +928,7 @@ static void rna_def_sculpt(BlenderRNA *brna)
|
|||
RNA_def_property_pointer_sdna(prop, NULL, "automasking_cavity_curve");
|
||||
RNA_def_property_struct_type(prop, "CurveMapping");
|
||||
RNA_def_property_ui_text(prop, "Cavity Curve", "Curve used for the sensitivity");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_cavity_editable");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
|
@ -905,6 +936,7 @@ static void rna_def_sculpt(BlenderRNA *brna)
|
|||
RNA_def_property_pointer_sdna(prop, NULL, "automasking_cavity_curve_op");
|
||||
RNA_def_property_struct_type(prop, "CurveMapping");
|
||||
RNA_def_property_ui_text(prop, "Cavity Curve", "Curve used for the sensitivity");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_cavity_editable");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
|
@ -914,12 +946,14 @@ static void rna_def_sculpt(BlenderRNA *brna)
|
|||
prop,
|
||||
"Area Normal",
|
||||
"Affect only vertices with a similar normal to where the stroke starts");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_area_normal_editable");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_automasking_view_normal", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "automasking_flags", BRUSH_AUTOMASKING_VIEW_NORMAL);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "View Normal", "Affect only vertices with a normal that faces the viewer");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_view_normal_editable");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "use_automasking_view_occlusion", PROP_BOOLEAN, PROP_NONE);
|
||||
|
@ -928,12 +962,14 @@ static void rna_def_sculpt(BlenderRNA *brna)
|
|||
prop,
|
||||
"Occlusion",
|
||||
"Only affect vertices that are not occluded by other faces. (Slower performance)");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_view_normal_editable");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "automasking_start_normal_limit", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "automasking_start_normal_limit");
|
||||
RNA_def_property_range(prop, 0.0001f, M_PI);
|
||||
RNA_def_property_ui_text(prop, "Area Normal Limit", "The range of angles that will be affected");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_area_normal_editable");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "automasking_start_normal_falloff", PROP_FLOAT, PROP_FACTOR);
|
||||
|
@ -941,6 +977,7 @@ static void rna_def_sculpt(BlenderRNA *brna)
|
|||
RNA_def_property_range(prop, 0.0001f, 1.0f);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Area Normal Falloff", "Extend the angular range with a falloff gradient");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_area_normal_editable");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "automasking_view_normal_limit", PROP_FLOAT, PROP_ANGLE);
|
||||
|
@ -956,6 +993,21 @@ static void rna_def_sculpt(BlenderRNA *brna)
|
|||
prop, "View Normal Falloff", "Extend the angular range with a falloff gradient");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "automasking_scene_view_normal_limit", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "automasking_scene_view_normal_limit");
|
||||
RNA_def_property_range(prop, 0.0001f, M_PI);
|
||||
RNA_def_property_ui_text(prop, "View Normal Limit", "The range of angles that will be affected");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_view_normal_editable");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "automasking_scene_view_normal_falloff", PROP_FLOAT, PROP_FACTOR);
|
||||
RNA_def_property_float_sdna(prop, NULL, "automasking_scene_view_normal_falloff");
|
||||
RNA_def_property_range(prop, 0.0001f, 1.0f);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "View Normal Falloff", "Extend the angular range with a falloff gradient");
|
||||
RNA_def_property_editable_func(prop, "rna_Scene_automasking_view_normal_editable");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "symmetrize_direction", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, rna_enum_symmetrize_direction_items);
|
||||
RNA_def_property_ui_text(prop, "Direction", "Source and destination for symmetrize operator");
|
||||
|
@ -1701,3 +1753,80 @@ void RNA_def_sculpt_paint(BlenderRNA *brna)
|
|||
}
|
||||
|
||||
#endif
|
||||
|
||||
static int rna_Scene_automasking_topology_editable(struct PointerRNA *ptr, const char **r_info) {
|
||||
Sculpt *sd = (Sculpt*)ptr->data;
|
||||
if (sd && (sd->paint.brush->automasking_flags & BRUSH_AUTOMASKING_TOPOLOGY)) {
|
||||
*r_info = "The active brush already has the same auto-masking enabled.";
|
||||
return PROP_INACTIVE | PROP_EDITABLE;
|
||||
}
|
||||
|
||||
return sd ? PROP_EDITABLE: 0;
|
||||
}
|
||||
|
||||
static int rna_Scene_automasking_face_sets_editable(struct PointerRNA *ptr, const char **r_info) {
|
||||
Sculpt *sd = (Sculpt*)ptr->data;
|
||||
if (sd && (sd->paint.brush->automasking_flags & BRUSH_AUTOMASKING_FACE_SETS)) {
|
||||
*r_info = "The active brush already has the same auto-masking enabled.";
|
||||
return PROP_INACTIVE | PROP_EDITABLE;
|
||||
}
|
||||
|
||||
return sd ? PROP_EDITABLE: 0;
|
||||
}
|
||||
|
||||
static int rna_Scene_automasking_mesh_boundary_editable(struct PointerRNA *ptr, const char **r_info) {
|
||||
Sculpt *sd = (Sculpt*)ptr->data;
|
||||
if (sd && (sd->paint.brush->automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_EDGES)) {
|
||||
*r_info = "The active brush already has the same auto-masking enabled.";
|
||||
return PROP_INACTIVE | PROP_EDITABLE;
|
||||
}
|
||||
|
||||
return sd ? PROP_EDITABLE: 0;
|
||||
}
|
||||
|
||||
static int rna_Scene_automasking_face_sets_boundary_editable(struct PointerRNA *ptr, const char **r_info) {
|
||||
Sculpt *sd = (Sculpt*)ptr->data;
|
||||
if (sd && (sd->paint.brush->automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS)) {
|
||||
*r_info = "The active brush already has the same auto-masking enabled.";
|
||||
return PROP_INACTIVE | PROP_EDITABLE;
|
||||
}
|
||||
|
||||
return sd ? PROP_EDITABLE: 0;
|
||||
}
|
||||
|
||||
static int rna_Scene_automasking_cavity_editable(struct PointerRNA *ptr, const char **r_info) {
|
||||
Sculpt *sd = (Sculpt*)ptr->data;
|
||||
if (sd && (sd->paint.brush->automasking_flags & BRUSH_AUTOMASKING_CAVITY_ALL)) {
|
||||
*r_info = "The active brush already has the same auto-masking enabled.";
|
||||
return PROP_INACTIVE | PROP_EDITABLE;
|
||||
}
|
||||
|
||||
return sd ? PROP_EDITABLE: 0;
|
||||
}
|
||||
|
||||
static int rna_Scene_automasking_view_normal_editable(struct PointerRNA *ptr, const char **r_info) {
|
||||
Sculpt *sd = (Sculpt*)ptr->data;
|
||||
|
||||
if (sd && (sd->paint.brush->automasking_flags & BRUSH_AUTOMASKING_VIEW_NORMAL)) {
|
||||
*r_info = "The active brush already has the same auto-masking enabled.";
|
||||
// TODO should probably utilize RNA_def_property_float_funcs to sync values between automasking_view and automasking_scene_view
|
||||
sd->automasking_scene_view_normal_limit = sd->automasking_view_normal_limit;
|
||||
Julian Eisel
commented
Do not change properties inside of an editable callback, these are meant to be mere queries and not modify data. Do not change properties inside of an editable callback, these are meant to be mere queries and not modify data.
Henry-Chang
commented
Agreed. Will definitely revert them. Agreed. Will definitely revert them.
|
||||
sd->automasking_scene_view_normal_falloff = sd->automasking_view_normal_falloff;
|
||||
return PROP_INACTIVE | PROP_EDITABLE;
|
||||
} else {
|
||||
sd->automasking_view_normal_limit = sd->automasking_scene_view_normal_limit;
|
||||
sd->automasking_view_normal_falloff = sd->automasking_scene_view_normal_falloff;
|
||||
}
|
||||
|
||||
return sd ? PROP_EDITABLE: 0;
|
||||
}
|
||||
|
||||
static int rna_Scene_automasking_area_normal_editable(struct PointerRNA *ptr, const char **r_info) {
|
||||
Sculpt *sd = (Sculpt*)ptr->data;
|
||||
if (sd && (sd->paint.brush->automasking_flags & BRUSH_AUTOMASKING_BRUSH_NORMAL)) {
|
||||
*r_info = "The active brush already has the same auto-masking enabled.";
|
||||
return PROP_INACTIVE | PROP_EDITABLE;
|
||||
}
|
||||
|
||||
return sd ? PROP_EDITABLE: 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Why is this change done here, it seems unrelated to the patch?
Wait I see that these properties were introduced just now. Then my question is, what are these properties doing? That's not immediately clear to me.
This is due specifically to the Occlusion toggle in View Normal setting. When Occlusion is selected, it will make the Limit and Falloff scroll bars in Brush Panel inactive. If the disabled_info is set at the RNA level, a "Disabled:" message would erroneously show up when hovering over View Normal Limit and View Normal Falloff in the Brush Panel. This would not be needed if disabled_info is set at the Python layout definition level.