Gizmo: add undo and name #104888

Open
Weizhen Huang wants to merge 5 commits from weizhen/blender:enable_gizmo_undo into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
4 changed files with 76 additions and 45 deletions
Showing only changes of commit 257ddba6ae - Show all commits

View File

@ -1080,6 +1080,15 @@ static int gizmo_cage2d_modal(bContext *C,
wmGizmoProperty *gz_prop;
gz_prop = WM_gizmo_target_property_find(gz, "size");
if (gz_prop->type != NULL) {
float size[2];
WM_gizmo_target_property_float_get_array(gz, gz_prop, size);
gz->matrix_offset[0][0] = size[0];
gz->matrix_offset[1][1] = size[1];
}
/* Overwrite if other properties exist. */
gz_prop = WM_gizmo_target_property_find(gz, "matrix");
if (gz_prop->type != NULL) {
WM_gizmo_target_property_float_get_array(gz, gz_prop, &gz->matrix_offset[0][0]);
@ -1215,6 +1224,15 @@ static int gizmo_cage2d_modal(bContext *C,
mul_m4_m4_post(gz->matrix_offset, matrix_scale);
}
gz_prop = WM_gizmo_target_property_find(gz, "size");
if (gz_prop->type != NULL) {
float size[2];
size[0] = gz->matrix_offset[0][0];
size[1] = gz->matrix_offset[1][1];
WM_gizmo_target_property_float_set_array(C, gz, gz_prop, size);
}
gz_prop = WM_gizmo_target_property_find(gz, "matrix");
if (gz_prop->type != NULL) {
WM_gizmo_target_property_float_set_array(C, gz, gz_prop, &gz->matrix_offset[0][0]);
}
@ -1236,6 +1254,23 @@ static void gizmo_cage2d_property_update(wmGizmo *gz, wmGizmoProperty *gz_prop)
BLI_assert(0);
}
}
else if (STREQ(gz_prop->type->idname, "size")) {
if (WM_gizmo_target_property_array_length(gz, gz_prop) == 2) {
float size[2];
WM_gizmo_target_property_float_get_array(gz, gz_prop, size);
gz->matrix_offset[0][0] = size[0];
int flag = RNA_enum_get(gz->ptr, "transform");
if (flag & ED_GIZMO_CAGE_XFORM_FLAG_SHAPE_UNIFORM) {
gz->matrix_offset[1][1] = size[0];
}
else {
gz->matrix_offset[1][1] = size[1];
}
}
else {
BLI_assert(0);
}
}
else {
BLI_assert(0);
}
@ -1253,7 +1288,15 @@ static void gizmo_cage2d_exit(bContext *C, wmGizmo *gz, const bool cancel)
wmGizmoProperty *gz_prop;
/* reset properties */
/* Reset properties. */
gz_prop = WM_gizmo_target_property_find(gz, "size");
if (gz_prop->type != NULL) {
float size[2];
size[0] = data->orig_matrix_offset[0][0];
size[1] = data->orig_matrix_offset[1][1];
WM_gizmo_target_property_float_set_array(C, gz, gz_prop, size);
}
gz_prop = WM_gizmo_target_property_find(gz, "matrix");
if (gz_prop->type != NULL) {
WM_gizmo_target_property_float_set_array(C, gz, gz_prop, &data->orig_matrix_offset[0][0]);
@ -1320,6 +1363,7 @@ static void GIZMO_GT_cage_2d(wmGizmoType *gzt)
"");
WM_gizmotype_target_property_def(gzt, "matrix", PROP_FLOAT, 16);
WM_gizmotype_target_property_def(gzt, "size", PROP_FLOAT, 2);
}
void ED_gizmotypes_cage_2d(void)

View File

@ -102,6 +102,7 @@ enum {
ED_GIZMO_CAGE_XFORM_FLAG_SCALE = (1 << 2), /* Scales */
ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM = (1 << 3), /* Scales uniformly */
ED_GIZMO_CAGE_XFORM_FLAG_SCALE_SIGNED = (1 << 4), /* Negative scale allowed */
ED_GIZMO_CAGE_XFORM_FLAG_SHAPE_UNIFORM = (1 << 5), /* Equal size along all axes */
};
/* draw_style */

View File

@ -192,7 +192,7 @@ static void WIDGETGROUP_light_spot_setup(const bContext *C, wmGizmoGroup *gzgrou
/* FIXME: this should ideally use RNA with a way to intercept the value and transform it based
* on the context (3D scene, viewport... etc), instead of using custom getter/setter and call
* `WM_gizmo_target_property_def_rna()` separately. The same comment applies to spot radius
* gizmo, light point gizmo and possibly light area gizmo. */
* gizmo and light point gizmo. */
WM_gizmo_target_property_def_func(gz,
"matrix",
&(const struct wmGizmoPropertyFnParams){
@ -416,40 +416,6 @@ void VIEW3D_GGT_light_point(wmGizmoGroupType *gzgt)
/** \name Area Light Gizmos
* \{ */
/* scale callbacks */
static void gizmo_area_light_prop_matrix_get(const wmGizmo *UNUSED(gz),
wmGizmoProperty *gz_prop,
void *value_p)
{
BLI_assert(gz_prop->type->array_length == 16);
float(*matrix)[4] = value_p;
const Light *la = gz_prop->custom_func.user_data;
matrix[0][0] = la->area_size;
matrix[1][1] = ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE) ? la->area_sizey :
la->area_size;
}
static void gizmo_area_light_prop_matrix_set(const wmGizmo *UNUSED(gz),
wmGizmoProperty *gz_prop,
const void *value_p)
{
const float(*matrix)[4] = value_p;
BLI_assert(gz_prop->type->array_length == 16);
Light *la = gz_prop->custom_func.user_data;
if (ELEM(la->area_shape, LA_AREA_RECT, LA_AREA_ELLIPSE)) {
la->area_size = len_v3(matrix[0]);
la->area_sizey = len_v3(matrix[1]);
}
else {
la->area_size = len_v3(matrix[0]);
}
DEG_id_tag_update(&la->id, ID_RECALC_COPY_ON_WRITE);
WM_main_add_notifier(NC_LAMP | ND_LIGHTING_DRAW, la);
}
static bool WIDGETGROUP_light_area_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
{
View3D *v3d = CTX_wm_view3d(C);
@ -506,18 +472,15 @@ static void WIDGETGROUP_light_area_refresh(const bContext *C, wmGizmoGroup *gzgr
int flag = ED_GIZMO_CAGE_XFORM_FLAG_SCALE;
if (ELEM(la->area_shape, LA_AREA_SQUARE, LA_AREA_DISK)) {
flag |= ED_GIZMO_CAGE_XFORM_FLAG_SCALE_UNIFORM;
flag |= ED_GIZMO_CAGE_XFORM_FLAG_SHAPE_UNIFORM;
}
RNA_enum_set(gz->ptr, "transform", flag);
/* Need to set property here for `la`. TODO: would prefer to do this in _init. */
WM_gizmo_target_property_def_func(gz,
"matrix",
&(const struct wmGizmoPropertyFnParams){
.value_get_fn = gizmo_area_light_prop_matrix_get,
.value_set_fn = gizmo_area_light_prop_matrix_set,
.range_get_fn = NULL,
.user_data = la,
});
PointerRNA lamp_ptr;
RNA_pointer_create(&la->id, &RNA_Light, la, &lamp_ptr);
/* Need to set property here for `lamp_ptr`. TODO: would prefer to do this in _init. */
WM_gizmo_target_property_def_rna(gz, "size", &lamp_ptr, "size_xy", -1);
}
void VIEW3D_GGT_light_area(wmGizmoGroupType *gzgt)

View File

@ -88,6 +88,20 @@ static void rna_Light_use_nodes_update(bContext *C, PointerRNA *ptr)
rna_Light_update(CTX_data_main(C), CTX_data_scene(C), ptr);
}
static void rna_area_light_size_get(PointerRNA *ptr, float *values)
{
Light *la = (Light *)ptr->data;
values[0] = la->area_size;
values[1] = la->area_sizey;
}
static void rna_area_light_size_set(PointerRNA *ptr, const float *values)
{
Light *la = (Light *)ptr->data;
la->area_size = values[0];
la->area_sizey = values[1];
}
#else
/* Don't define icons here, so they don't show up in the Light UI (properties Editor) - DingTo */
const EnumPropertyItem rna_enum_light_type_items[] = {
@ -452,6 +466,7 @@ static void rna_def_area_light(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Shape", "Shape of the area Light");
RNA_def_property_update(prop, 0, "rna_Light_draw_update");
/* TODO: deprecate `size` and `size_y`, rename `size_xy` to `size`. */
prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "area_size");
RNA_def_property_range(prop, 0.0f, FLT_MAX);
@ -470,6 +485,14 @@ static void rna_def_area_light(BlenderRNA *brna)
"Size of the area of the area light in the Y direction for rectangle shapes");
RNA_def_property_update(prop, 0, "rna_Light_draw_update");
prop = RNA_def_property(srna, "size_xy", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_array(prop, 2);
RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 0, 100, 0.1, 3);
RNA_def_property_float_funcs(prop, "rna_area_light_size_get", "rna_area_light_size_set", NULL);
RNA_def_property_ui_text(prop, "Area Size", "Size of the area light");
RNA_def_property_update(prop, 0, "rna_Light_draw_update");
prop = RNA_def_property(srna, "spread", PROP_FLOAT, PROP_ANGLE);
RNA_def_property_float_sdna(prop, NULL, "area_spread");
RNA_def_property_range(prop, DEG2RADF(0.0f), DEG2RADF(180.0f));