Fix #54325: Shrink/Fatten "Offset Even" can not be used as default

The default keymap item that triggers `Shrink/Fatten` uses the `Alt`
modifier, which coincidentally is the same key that toggles
`Offset Even`. What is undesirable.

The solution is to alternate between Alt Press and Alt Release
depending on the `Offset Even` property.

Pull Request: https://projects.blender.org/blender/blender/pulls/141904
This commit is contained in:
Germano Cavalcante
2025-07-15 01:56:25 +02:00
committed by Germano Cavalcante
parent 8feef54afa
commit 32a6e14d41

View File

@@ -22,6 +22,8 @@
#include "BLT_translation.hh"
#include "RNA_access.hh"
#include "transform.hh"
#include "transform_convert.hh"
#include "transform_snap.hh"
@@ -34,15 +36,31 @@ namespace blender::ed::transform {
/** \name Transform (Shrink-Fatten)
* \{ */
enum eShrinkFattenMode {
EVEN_THICKNESS_OFF = 0,
EVEN_THICKNESS_ON = 1,
};
/**
* Custom data, stored in #TransInfo.custom.mode.data
*/
struct ShrinkFattenCustomData {
const wmKeyMapItem *kmi;
eShrinkFattenMode mode;
bool use_alt_press_to_disable;
};
static void transdata_elem_shrink_fatten(const TransInfo *t,
const TransDataContainer * /*tc*/,
TransData *td,
TransDataExtension *td_ext,
const float distance)
{
ShrinkFattenCustomData *custom_data = static_cast<ShrinkFattenCustomData *>(t->custom.mode.data);
/* Get the final offset. */
float tdistance = distance * td->factor;
if (td_ext && (t->flag & T_ALT_TRANSFORM) != 0) {
if (td_ext && custom_data->mode == EVEN_THICKNESS_ON) {
tdistance *= td_ext->iscale[0]; /* Shell factor. */
}
@@ -51,16 +69,22 @@ static void transdata_elem_shrink_fatten(const TransInfo *t,
static eRedrawFlag shrinkfatten_handleEvent(TransInfo *t, const wmEvent *event)
{
if (t->redraw) {
/* Event already handled. */
return TREDRAW_NOTHING;
}
BLI_assert(t->mode == TFM_SHRINKFATTEN);
const wmKeyMapItem *kmi = static_cast<const wmKeyMapItem *>(t->custom.mode.data);
if (kmi && event->type == kmi->type && event->val == kmi->val) {
ShrinkFattenCustomData *custom_data = static_cast<ShrinkFattenCustomData *>(t->custom.mode.data);
const wmKeyMapItem *kmi = custom_data->kmi;
if (ELEM(event->type, EVT_LEFTALTKEY, EVT_RIGHTALTKEY)) {
bool use_even_thickness = custom_data->use_alt_press_to_disable != (event->val == KM_PRESS);
custom_data->mode = use_even_thickness ? EVEN_THICKNESS_ON : EVEN_THICKNESS_OFF;
return TREDRAW_HARD;
}
else if (kmi && event->type == kmi->type && event->val == kmi->val) {
/* Allows the "Even Thickness" effect to be enabled as a toggle. */
t->flag ^= T_ALT_TRANSFORM;
custom_data->mode = custom_data->mode == EVEN_THICKNESS_ON ? EVEN_THICKNESS_OFF :
EVEN_THICKNESS_ON;
/* Also toggle the Alt press state. */
custom_data->use_alt_press_to_disable = !custom_data->use_alt_press_to_disable;
return TREDRAW_HARD;
}
return TREDRAW_NOTHING;
@@ -71,6 +95,7 @@ static void applyShrinkFatten(TransInfo *t)
float distance;
fmt::memory_buffer str;
const UnitSettings &unit = t->scene->unit;
ShrinkFattenCustomData *custom_data = static_cast<ShrinkFattenCustomData *>(t->custom.mode.data);
distance = t->values[0] + t->values_modal_offset[0];
@@ -105,14 +130,14 @@ static void applyShrinkFatten(TransInfo *t)
}
fmt::format_to(fmt::appender(str), ", (");
const wmKeyMapItem *kmi = static_cast<const wmKeyMapItem *>(t->custom.mode.data);
const wmKeyMapItem *kmi = custom_data->kmi;
if (kmi) {
str.append(WM_keymap_item_to_string(kmi, false).value_or(""));
}
fmt::format_to(fmt::appender(str),
fmt::runtime(IFACE_(" or Alt) Even Thickness {}")),
WM_bool_as_string((t->flag & T_ALT_TRANSFORM) != 0));
WM_bool_as_string(custom_data->mode == EVEN_THICKNESS_ON));
/* Done with header string. */
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
@@ -133,7 +158,7 @@ static void applyShrinkFatten(TransInfo *t)
ED_area_status_text(t->area, fmt::to_string(str).c_str());
}
static void initShrinkFatten(TransInfo *t, wmOperator * /*op*/)
static void initShrinkFatten(TransInfo *t, wmOperator *op)
{
if ((t->flag & T_EDIT) == 0 || (t->obedit_type != OB_MESH)) {
BKE_report(t->reports, RPT_ERROR, "'Shrink/Fatten' meshes is only supported in edit mode");
@@ -153,9 +178,31 @@ static void initShrinkFatten(TransInfo *t, wmOperator * /*op*/)
t->num.unit_sys = t->scene->unit.system;
t->num.unit_type[0] = B_UNIT_LENGTH;
ShrinkFattenCustomData *custom_data = static_cast<ShrinkFattenCustomData *>(
MEM_callocN(sizeof(*custom_data), __func__));
t->custom.mode.data = custom_data;
t->custom.mode.free_cb = [](TransInfo *t, TransDataContainer *, TransCustomData *custom_data) {
ShrinkFattenCustomData *data = static_cast<ShrinkFattenCustomData *>(custom_data->data);
/* WORKAROUND: Use #T_ALT_TRANSFORM to indicate the value of the "use_even_offset" property in
* `saveTransform`. */
SET_FLAG_FROM_TEST(t->flag, data->mode == EVEN_THICKNESS_ON, T_ALT_TRANSFORM);
MEM_freeN(data);
custom_data->data = nullptr;
};
if (t->keymap) {
/* Workaround to use the same key as the modal keymap. */
t->custom.mode.data = (void *)WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE);
custom_data->kmi = WM_modalkeymap_find_propvalue(t->keymap, TFM_MODAL_RESIZE);
}
if (op) {
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "use_even_offset");
if (RNA_property_is_set(op->ptr, prop) && RNA_property_boolean_get(op->ptr, prop)) {
/* TODO: Check if the Alt button is already pressed. */
custom_data->mode = EVEN_THICKNESS_ON;
custom_data->use_alt_press_to_disable = true;
}
}
}