From 8d1bf196caf9ea144d0b6a10f5ee3291020de657 Mon Sep 17 00:00:00 2001 From: Henry Chang Date: Sat, 25 Mar 2023 19:24:43 +0800 Subject: [PATCH 01/11] UI: Gray out Scene Auto-Masking if equivalent Brush option --- scripts/startup/bl_ui/space_view3d.py | 29 ++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py index b60988353fc..817dfc5d826 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -7854,25 +7854,39 @@ class VIEW3D_PT_sculpt_automasking(Panel): layout = self.layout tool_settings = context.tool_settings + data = 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.enabled = not data.use_automasking_topology + sub.prop(sculpt, "use_automasking_topology", text="Topology") + + sub = col.column() + sub.enabled = not data.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.enabled = not data.use_automasking_boundary_edges + sub.prop(sculpt, "use_automasking_boundary_edges", text="Mesh Boundary") + + sub = col.column() + sub.enabled = not data.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.enabled = not data.use_automasking_boundary_edges or not data.use_automasking_boundary_face_sets + sub.prop(sculpt.brush, "automasking_boundary_edges_propagation_steps") col.separator() col = layout.column(align=True) + col.enabled = not data.use_automasking_cavity and not data.use_automasking_cavity_inverted row = col.row() row.prop(sculpt, "use_automasking_cavity", text="Cavity") @@ -7886,10 +7900,12 @@ class VIEW3D_PT_sculpt_automasking(Panel): if is_cavity_active: col = layout.column(align=True) + col.enabled = not data.use_automasking_cavity_inverted and not data.use_automasking_cavity col.prop(sculpt, "automasking_cavity_factor", text="Factor") col.prop(sculpt, "automasking_cavity_blur_steps", text="Blur") col = layout.column() + col.enabled = not data.use_automasking_cavity_inverted and not data.use_automasking_cavity col.prop(sculpt, "use_automasking_custom_cavity_curve", text="Custom Curve") if sculpt.use_automasking_custom_cavity_curve: @@ -7898,6 +7914,7 @@ class VIEW3D_PT_sculpt_automasking(Panel): col.separator() col = layout.column(align=True) + col.enabled = not data.use_automasking_view_normal col.prop(sculpt, "use_automasking_view_normal", text="View Normal") if sculpt.use_automasking_view_normal: @@ -7908,10 +7925,12 @@ class VIEW3D_PT_sculpt_automasking(Panel): subcol.prop(sculpt, "automasking_view_normal_falloff", text="Falloff") col = layout.column() + col.enabled = not data.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.enabled = not data.use_automasking_start_normal col.prop(sculpt, "automasking_start_normal_limit", text="Limit") col.prop(sculpt, "automasking_start_normal_falloff", text="Falloff") -- 2.30.2 From 9eb92494680eaf7b98abed6b0f0e04afd4245b4b Mon Sep 17 00:00:00 2001 From: Henry Chang Date: Sat, 25 Mar 2023 19:26:07 +0800 Subject: [PATCH 02/11] WIP: Hardcoded Disabled Message for Gray out Scene Auto-masking --- source/blender/editors/interface/interface_region_tooltip.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface_region_tooltip.cc b/source/blender/editors/interface/interface_region_tooltip.cc index fb87d940506..a689b7749bc 100644 --- a/source/blender/editors/interface/interface_region_tooltip.cc +++ b/source/blender/editors/interface/interface_region_tooltip.cc @@ -903,7 +903,10 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C, bool disabled_msg_free = false; /* If operator poll check failed, it can give pretty precise info why. */ - if (optype) { + if (strcmp(rna_struct.strinfo, "SCULPT_OT_mask_from_cavity") == 0 || strstr(rna_prop.strinfo, "automasking")) { + disabled_msg = "The active brush already has the same auto-masking enabled."; + } + else if (optype) { const wmOperatorCallContext opcontext = extra_icon ? extra_icon->optype_params->opcontext : but->opcontext; wmOperatorCallParams call_params{}; -- 2.30.2 From 5083211921a3b6e417639483ecdd3c6760ad61f3 Mon Sep 17 00:00:00 2001 From: Henry Chang Date: Wed, 29 Mar 2023 06:36:15 +0800 Subject: [PATCH 03/11] UI: Updated Gray out (with Active) Scene Auto-Masking if equivalent Brush option --- scripts/startup/bl_ui/space_view3d.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py index 817dfc5d826..2f51a6ca0d2 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -7860,33 +7860,33 @@ class VIEW3D_PT_sculpt_automasking(Panel): col = layout.column(align=True) sub = col.column() - sub.enabled = not data.use_automasking_topology + sub.active = not data.use_automasking_topology sub.prop(sculpt, "use_automasking_topology", text="Topology") sub = col.column() - sub.enabled = not data.use_automasking_face_sets + sub.active = not data.use_automasking_face_sets sub.prop(sculpt, "use_automasking_face_sets", text="Face Sets") col.separator() col = layout.column(align=True) sub = col.column() - sub.enabled = not data.use_automasking_boundary_edges + sub.active = not data.use_automasking_boundary_edges sub.prop(sculpt, "use_automasking_boundary_edges", text="Mesh Boundary") sub = col.column() - sub.enabled = not data.use_automasking_boundary_face_sets + sub.active = not data.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: sub = col.column() - sub.enabled = not data.use_automasking_boundary_edges or not data.use_automasking_boundary_face_sets + sub.active = not data.use_automasking_boundary_edges or not data.use_automasking_boundary_face_sets sub.prop(sculpt.brush, "automasking_boundary_edges_propagation_steps") col.separator() col = layout.column(align=True) - col.enabled = not data.use_automasking_cavity and not data.use_automasking_cavity_inverted + col.active = not data.use_automasking_cavity and not data.use_automasking_cavity_inverted row = col.row() row.prop(sculpt, "use_automasking_cavity", text="Cavity") @@ -7900,12 +7900,12 @@ class VIEW3D_PT_sculpt_automasking(Panel): if is_cavity_active: col = layout.column(align=True) - col.enabled = not data.use_automasking_cavity_inverted and not data.use_automasking_cavity + col.active = not data.use_automasking_cavity_inverted and not data.use_automasking_cavity col.prop(sculpt, "automasking_cavity_factor", text="Factor") col.prop(sculpt, "automasking_cavity_blur_steps", text="Blur") col = layout.column() - col.enabled = not data.use_automasking_cavity_inverted and not data.use_automasking_cavity + col.active = not data.use_automasking_cavity_inverted and not data.use_automasking_cavity col.prop(sculpt, "use_automasking_custom_cavity_curve", text="Custom Curve") if sculpt.use_automasking_custom_cavity_curve: @@ -7914,7 +7914,7 @@ class VIEW3D_PT_sculpt_automasking(Panel): col.separator() col = layout.column(align=True) - col.enabled = not data.use_automasking_view_normal + col.active = not data.use_automasking_view_normal col.prop(sculpt, "use_automasking_view_normal", text="View Normal") if sculpt.use_automasking_view_normal: @@ -7925,12 +7925,12 @@ class VIEW3D_PT_sculpt_automasking(Panel): subcol.prop(sculpt, "automasking_view_normal_falloff", text="Falloff") col = layout.column() - col.enabled = not data.use_automasking_start_normal + col.active = not data.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.enabled = not data.use_automasking_start_normal + col.active = not data.use_automasking_start_normal col.prop(sculpt, "automasking_start_normal_limit", text="Limit") col.prop(sculpt, "automasking_start_normal_falloff", text="Falloff") -- 2.30.2 From f69302fdd766cd5be0d3e662e4f49c32f414fc7a Mon Sep 17 00:00:00 2001 From: Henry Chang Date: Wed, 29 Mar 2023 06:58:29 +0800 Subject: [PATCH 04/11] WIP: Updated Hardcoded Disabled Message for Gray out (with Active) Scene Auto-masking --- .../interface/interface_region_tooltip.cc | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/source/blender/editors/interface/interface_region_tooltip.cc b/source/blender/editors/interface/interface_region_tooltip.cc index a689b7749bc..099fc116a60 100644 --- a/source/blender/editors/interface/interface_region_tooltip.cc +++ b/source/blender/editors/interface/interface_region_tooltip.cc @@ -897,16 +897,25 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C, MEM_freeN(str); } + if (but->flag & UI_BUT_INACTIVE) { + const char *inactive_msg = nullptr; + if ((rna_struct.strinfo && strcmp(rna_struct.strinfo, "SCULPT_OT_mask_from_cavity") == 0) || (rna_prop.strinfo && strstr(rna_prop.strinfo, "automasking"))) { + inactive_msg = "The active brush already has the same auto-masking enabled."; + } + if (inactive_msg && inactive_msg[0]) { + uiTooltipField *field = text_field_add( + data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Alert); + field->text = BLI_sprintfN(TIP_("Disabled: %s"), inactive_msg); + } + } + /* Button is disabled, we may be able to tell user why. */ if ((but->flag & UI_BUT_DISABLED) || extra_icon) { const char *disabled_msg = nullptr; bool disabled_msg_free = false; /* If operator poll check failed, it can give pretty precise info why. */ - if (strcmp(rna_struct.strinfo, "SCULPT_OT_mask_from_cavity") == 0 || strstr(rna_prop.strinfo, "automasking")) { - disabled_msg = "The active brush already has the same auto-masking enabled."; - } - else if (optype) { + if (optype) { const wmOperatorCallContext opcontext = extra_icon ? extra_icon->optype_params->opcontext : but->opcontext; wmOperatorCallParams call_params{}; -- 2.30.2 From d0c42cdf63cbe80a6d18c8d6d2b3c1ab9bf3521e Mon Sep 17 00:00:00 2001 From: Henry Chang Date: Thu, 6 Apr 2023 15:00:52 +0800 Subject: [PATCH 05/11] Revert all changes back to main branch state --- scripts/startup/bl_ui/space_view3d.py | 29 ++++--------------- .../interface/interface_region_tooltip.cc | 12 -------- 2 files changed, 5 insertions(+), 36 deletions(-) diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py index 2f51a6ca0d2..b60988353fc 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -7854,39 +7854,25 @@ class VIEW3D_PT_sculpt_automasking(Panel): layout = self.layout tool_settings = context.tool_settings - data = tool_settings.sculpt.brush sculpt = tool_settings.sculpt layout.label(text="Auto-Masking") col = layout.column(align=True) - sub = col.column() - sub.active = not data.use_automasking_topology - sub.prop(sculpt, "use_automasking_topology", text="Topology") - - sub = col.column() - sub.active = not data.use_automasking_face_sets - sub.prop(sculpt, "use_automasking_face_sets", text="Face Sets") + col.prop(sculpt, "use_automasking_topology", text="Topology") + col.prop(sculpt, "use_automasking_face_sets", text="Face Sets") col.separator() col = layout.column(align=True) - sub = col.column() - sub.active = not data.use_automasking_boundary_edges - sub.prop(sculpt, "use_automasking_boundary_edges", text="Mesh Boundary") - - sub = col.column() - sub.active = not data.use_automasking_boundary_face_sets - sub.prop(sculpt, "use_automasking_boundary_face_sets", text="Face Sets Boundary") + col.prop(sculpt, "use_automasking_boundary_edges", text="Mesh 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: - sub = col.column() - sub.active = not data.use_automasking_boundary_edges or not data.use_automasking_boundary_face_sets - sub.prop(sculpt.brush, "automasking_boundary_edges_propagation_steps") + col.prop(sculpt.brush, "automasking_boundary_edges_propagation_steps") col.separator() col = layout.column(align=True) - col.active = not data.use_automasking_cavity and not data.use_automasking_cavity_inverted row = col.row() row.prop(sculpt, "use_automasking_cavity", text="Cavity") @@ -7900,12 +7886,10 @@ class VIEW3D_PT_sculpt_automasking(Panel): if is_cavity_active: col = layout.column(align=True) - col.active = not data.use_automasking_cavity_inverted and not data.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 data.use_automasking_cavity_inverted and not data.use_automasking_cavity col.prop(sculpt, "use_automasking_custom_cavity_curve", text="Custom Curve") if sculpt.use_automasking_custom_cavity_curve: @@ -7914,7 +7898,6 @@ class VIEW3D_PT_sculpt_automasking(Panel): col.separator() col = layout.column(align=True) - col.active = not data.use_automasking_view_normal col.prop(sculpt, "use_automasking_view_normal", text="View Normal") if sculpt.use_automasking_view_normal: @@ -7925,12 +7908,10 @@ class VIEW3D_PT_sculpt_automasking(Panel): subcol.prop(sculpt, "automasking_view_normal_falloff", text="Falloff") col = layout.column() - col.active = not data.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 data.use_automasking_start_normal col.prop(sculpt, "automasking_start_normal_limit", text="Limit") col.prop(sculpt, "automasking_start_normal_falloff", text="Falloff") diff --git a/source/blender/editors/interface/interface_region_tooltip.cc b/source/blender/editors/interface/interface_region_tooltip.cc index 099fc116a60..fb87d940506 100644 --- a/source/blender/editors/interface/interface_region_tooltip.cc +++ b/source/blender/editors/interface/interface_region_tooltip.cc @@ -897,18 +897,6 @@ static uiTooltipData *ui_tooltip_data_from_button_or_extra_icon(bContext *C, MEM_freeN(str); } - if (but->flag & UI_BUT_INACTIVE) { - const char *inactive_msg = nullptr; - if ((rna_struct.strinfo && strcmp(rna_struct.strinfo, "SCULPT_OT_mask_from_cavity") == 0) || (rna_prop.strinfo && strstr(rna_prop.strinfo, "automasking"))) { - inactive_msg = "The active brush already has the same auto-masking enabled."; - } - if (inactive_msg && inactive_msg[0]) { - uiTooltipField *field = text_field_add( - data, uiTooltipFormat::Style::Normal, uiTooltipFormat::ColorID::Alert); - field->text = BLI_sprintfN(TIP_("Disabled: %s"), inactive_msg); - } - } - /* Button is disabled, we may be able to tell user why. */ if ((but->flag & UI_BUT_DISABLED) || extra_icon) { const char *disabled_msg = nullptr; -- 2.30.2 From 32b5ced13b4a21c6b9c000935984a7554ac4ed8a Mon Sep 17 00:00:00 2001 From: Henry Chang Date: Thu, 6 Apr 2023 15:36:39 +0800 Subject: [PATCH 06/11] WIP: Modifications that will allow Disabled messages to be added without setting editable to false --- source/blender/editors/include/UI_interface.h | 1 + source/blender/editors/interface/interface.cc | 14 +++++++++ source/blender/makesrna/RNA_access.h | 1 + source/blender/makesrna/RNA_types.h | 9 ++++++ source/blender/makesrna/intern/rna_access.cc | 31 +++++++++++++++++++ 5 files changed, 56 insertions(+) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index de3169d045b..96ca17b20bf 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -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_inactive(uiBut *but, const char *disabled_hint); void UI_but_type_set_menu_from_pulldown(uiBut *but); diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index 94eeab27159..0b886095491 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -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_inactive(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,6 +5908,16 @@ void UI_but_dragflag_disable(uiBut *but, int flag) but->dragflag &= ~flag; } +void UI_but_inactive(uiBut *but, const char *inactive_hint) +{ + /* Only one inactive hint at a time currently. Don't override the previous one here. */ + if (but->disabled_info && but->disabled_info[0]) { + return; + } + + but->disabled_info = inactive_hint; +} + void UI_but_disable(uiBut *but, const char *disabled_hint) { UI_but_flag_enable(but, UI_BUT_DISABLED); diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 14d7c6691f6..4e05d9f56be 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -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. */ diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h index 568eea48ec1..4a10af9bf32 100644 --- a/source/blender/makesrna/RNA_types.h +++ b/source/blender/makesrna/RNA_types.h @@ -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 diff --git a/source/blender/makesrna/intern/rna_access.cc b/source/blender/makesrna/intern/rna_access.cc index c1030d80196..85b89f4c93a 100644 --- a/source/blender/makesrna/intern/rna_access.cc +++ b/source/blender/makesrna/intern/rna_access.cc @@ -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); -- 2.30.2 From aa6fa9badd9c2924bdf95e62d31f72eb85a66345 Mon Sep 17 00:00:00 2001 From: Henry Chang Date: Thu, 6 Apr 2023 16:50:21 +0800 Subject: [PATCH 07/11] UI: Scene Automasking Panel Inactive with Disabled Message except 'Create Mask' Button --- scripts/startup/bl_ui/space_view3d.py | 40 ++++-- .../interface/interface_region_tooltip.cc | 4 +- source/blender/makesrna/intern/rna_brush.c | 11 ++ .../makesrna/intern/rna_sculpt_paint.c | 136 ++++++++++++++++-- 4 files changed, 168 insertions(+), 23 deletions(-) diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py index b60988353fc..387eee9767a 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -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.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,6 +7919,7 @@ 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: @@ -7908,10 +7930,12 @@ class VIEW3D_PT_sculpt_automasking(Panel): subcol.prop(sculpt, "automasking_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") diff --git a/source/blender/editors/interface/interface_region_tooltip.cc b/source/blender/editors/interface/interface_region_tooltip.cc index fb87d940506..f67bd1b405b 100644 --- a/source/blender/editors/interface/interface_region_tooltip.cc +++ b/source/blender/editors/interface/interface_region_tooltip.cc @@ -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) { const char *disabled_msg = nullptr; bool disabled_msg_free = false; diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 033090f2f5b..6e9c8de6de6 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -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; +} diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index aa60339b7b8..c9af5d11555 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -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,12 +977,14 @@ 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); RNA_def_property_float_sdna(prop, NULL, "automasking_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_view_normal_falloff", PROP_FLOAT, PROP_FACTOR); @@ -954,6 +992,7 @@ static void rna_def_sculpt(BlenderRNA *brna) 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); @@ -1701,3 +1740,74 @@ 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."; + return PROP_INACTIVE | PROP_EDITABLE; + } + + 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; +} -- 2.30.2 From a6777367d2800ae6c1255e7d61337aeb4241dee0 Mon Sep 17 00:00:00 2001 From: Henry Chang Date: Thu, 6 Apr 2023 16:58:03 +0800 Subject: [PATCH 08/11] UI: Scene Automasking 'Create Mask' Button Disabled with Disabled Message --- source/blender/editors/sculpt_paint/sculpt.cc | 13 +++++++++++++ .../blender/editors/sculpt_paint/sculpt_intern.hh | 1 + source/blender/editors/sculpt_paint/sculpt_ops.cc | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/sculpt_paint/sculpt.cc b/source/blender/editors/sculpt_paint/sculpt.cc index 077a16cf4df..cbe212c5074 100644 --- a/source/blender/editors/sculpt_paint/sculpt.cc +++ b/source/blender/editors/sculpt_paint/sculpt.cc @@ -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)) { + 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)); diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.hh b/source/blender/editors/sculpt_paint/sculpt_intern.hh index fae073233a6..3659eb010de 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.hh +++ b/source/blender/editors/sculpt_paint/sculpt_intern.hh @@ -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. diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.cc b/source/blender/editors/sculpt_paint/sculpt_ops.cc index 9a975fb5ced..da13065ad10 100644 --- a/source/blender/editors/sculpt_paint/sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/sculpt_ops.cc @@ -1243,7 +1243,7 @@ static void SCULPT_OT_mask_from_cavity(wmOperatorType *ot) /* api callbacks */ ot->exec = sculpt_bake_cavity_exec; - ot->poll = SCULPT_mode_poll; + ot->poll = SCULPT_mode_poll_cavity_automask; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -- 2.30.2 From 5b9616e1f85435ebadc83bf62611d3c81240fcd7 Mon Sep 17 00:00:00 2001 From: Henry Chang Date: Thu, 6 Apr 2023 17:32:32 +0800 Subject: [PATCH 09/11] WIP: Separate 'Create Mask' Button and View Normal Limit and Falloff between Scene and Brush Panel --- scripts/startup/bl_ui/space_view3d.py | 6 +++--- source/blender/blenkernel/intern/paint.cc | 2 ++ source/blender/editors/sculpt_paint/sculpt_ops.cc | 10 +++++++++- source/blender/makesdna/DNA_scene_types.h | 1 + source/blender/makesrna/intern/rna_sculpt_paint.c | 15 ++++++++++++++- 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/scripts/startup/bl_ui/space_view3d.py b/scripts/startup/bl_ui/space_view3d.py index 387eee9767a..5d26059384c 100644 --- a/scripts/startup/bl_ui/space_view3d.py +++ b/scripts/startup/bl_ui/space_view3d.py @@ -7896,7 +7896,7 @@ class VIEW3D_PT_sculpt_automasking(Panel): if is_cavity_active: subrow = row.column(align=True) subrow.enabled = not brush.use_automasking_cavity and not brush.use_automasking_cavity_inverted - props = subrow.operator("sculpt.mask_from_cavity", text="Create Mask") + props = subrow.operator("sculpt.scene_mask_from_cavity", text="Create Mask") props.settings_source = "SCENE" subcol = col.column(align=True) @@ -7926,8 +7926,8 @@ class VIEW3D_PT_sculpt_automasking(Panel): 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 diff --git a/source/blender/blenkernel/intern/paint.cc b/source/blender/blenkernel/intern/paint.cc index 943f6902868..dcced0e6f9b 100644 --- a/source/blender/blenkernel/intern/paint.cc +++ b/source/blender/blenkernel/intern/paint.cc @@ -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; } diff --git a/source/blender/editors/sculpt_paint/sculpt_ops.cc b/source/blender/editors/sculpt_paint/sculpt_ops.cc index da13065ad10..20c4b9c5e34 100644 --- a/source/blender/editors/sculpt_paint/sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/sculpt_ops.cc @@ -1243,7 +1243,7 @@ static void SCULPT_OT_mask_from_cavity(wmOperatorType *ot) /* api callbacks */ ot->exec = sculpt_bake_cavity_exec; - ot->poll = SCULPT_mode_poll_cavity_automask; + ot->poll = SCULPT_mode_poll; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -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); } diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index ca1d878110f..0305696bb8e 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -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. */ diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index c9af5d11555..d97da7b076b 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -984,12 +984,25 @@ static void rna_def_sculpt(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "automasking_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_view_normal_falloff", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "automasking_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_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"); -- 2.30.2 From d232b8800ad5ee4fead8f81f58865d7c664c0bff Mon Sep 17 00:00:00 2001 From: Henry Chang Date: Thu, 6 Apr 2023 17:44:12 +0800 Subject: [PATCH 10/11] WIP: Extra: Sync Values between Scene View Normal Limit, Falloff and Brush View Normal Limit, Falloff --- source/blender/makesrna/intern/rna_sculpt_paint.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c index d97da7b076b..592936000df 100644 --- a/source/blender/makesrna/intern/rna_sculpt_paint.c +++ b/source/blender/makesrna/intern/rna_sculpt_paint.c @@ -1809,7 +1809,13 @@ static int rna_Scene_automasking_view_normal_editable(struct PointerRNA *ptr, co 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; + 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; -- 2.30.2 From 0a80f192b67e86f6675ab59653db1642c2542ca5 Mon Sep 17 00:00:00 2001 From: Henry Chang Date: Sun, 14 May 2023 12:21:40 +0800 Subject: [PATCH 11/11] Fix: UI_but_inactive to UI_but_set_disabled_hint --- source/blender/editors/include/UI_interface.h | 2 +- source/blender/editors/interface/interface.cc | 23 ++++++++----------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 96ca17b20bf..0842d8432c0 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -896,7 +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_inactive(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); diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc index 0b886095491..9ea07d1ae13 100644 --- a/source/blender/editors/interface/interface.cc +++ b/source/blender/editors/interface/interface.cc @@ -4716,7 +4716,7 @@ static uiBut *ui_def_but_rna(uiBlock *block, } if (but->rnapoin.data && RNA_property_is_inactive_info(&but->rnapoin, prop, &info)) { - UI_but_inactive(but, info); + UI_but_set_disabled_hint(but, info); } if (proptype == PROP_POINTER) { @@ -5908,20 +5908,8 @@ void UI_but_dragflag_disable(uiBut *but, int flag) but->dragflag &= ~flag; } -void UI_but_inactive(uiBut *but, const char *inactive_hint) +void UI_but_set_disabled_hint(uiBut *but, const char *disabled_hint) { - /* Only one inactive hint at a time currently. Don't override the previous one here. */ - if (but->disabled_info && but->disabled_info[0]) { - return; - } - - but->disabled_info = inactive_hint; -} - -void UI_but_disable(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; @@ -5930,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); -- 2.30.2