Fix UV gizmos poll failing with multiple objects

Only the active objects UV selection was checked.
This also avoids checking UV selection for every poll call,
now this is only done on refresh.
This commit is contained in:
Campbell Barton
2020-01-09 17:50:52 +11:00
parent ce5a5b553d
commit f681e9ea49
3 changed files with 143 additions and 115 deletions

View File

@@ -65,6 +65,12 @@ bool ED_uvedit_center_multi(const struct Scene *scene,
float r_cent[2],
char mode);
bool ED_uvedit_center_from_pivot_ex(struct SpaceImage *sima,
struct Scene *scene,
struct ViewLayer *view_layer,
float r_center[2],
char mode,
bool *r_has_select);
bool ED_uvedit_center_from_pivot(struct SpaceImage *sima,
struct Scene *scene,
struct ViewLayer *view_layer,

View File

@@ -58,6 +58,30 @@
/** \name Shared Callback's
*/
static bool gizmo2d_generic_poll(const bContext *C, wmGizmoGroupType *gzgt)
{
if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) {
return false;
}
if ((U.gizmo_flag & USER_GIZMO_DRAW) == 0) {
return false;
}
ScrArea *sa = CTX_wm_area(C);
switch (sa->spacetype) {
case SPACE_IMAGE: {
SpaceImage *sima = sa->spacedata.first;
Object *obedit = CTX_data_edit_object(C);
if (!ED_space_image_show_uvedit(sima, obedit)) {
return false;
}
}
}
return true;
}
static void gizmo2d_pivot_point_message_subscribe(struct wmGizmoGroup *gzgroup,
struct wmMsgBus *mbus,
/* Additional args. */
@@ -180,7 +204,7 @@ static GizmoGroup2D *gizmogroup2d_init(wmGizmoGroup *gzgroup)
/**
* Calculates origin in view space, use with #gizmo2d_origin_to_region.
*/
static void gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min, float *r_max)
static bool gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min, float *r_max)
{
float min_buf[2], max_buf[2];
if (r_min == NULL) {
@@ -191,6 +215,7 @@ static void gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min
}
ScrArea *sa = CTX_wm_area(C);
bool changed = false;
if (sa->spacetype == SPACE_IMAGE) {
SpaceImage *sima = sa->spacedata.first;
Scene *scene = CTX_data_scene(C);
@@ -199,29 +224,33 @@ static void gizmo2d_calc_bounds(const bContext *C, float *r_center, float *r_min
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
view_layer, NULL, &objects_len);
if (!ED_uvedit_minmax_multi(scene, ima, objects, objects_len, r_min, r_max)) {
zero_v2(r_min);
zero_v2(r_max);
if (ED_uvedit_minmax_multi(scene, ima, objects, objects_len, r_min, r_max)) {
changed = true;
}
MEM_freeN(objects);
}
else {
if (changed == false) {
zero_v2(r_min);
zero_v2(r_max);
}
mid_v2_v2v2(r_center, r_min, r_max);
return changed;
}
static void gizmo2d_calc_center(const bContext *C, float r_center[2])
static bool gizmo2d_calc_center(const bContext *C, float r_center[2])
{
ScrArea *sa = CTX_wm_area(C);
bool has_select = false;
zero_v2(r_center);
if (sa->spacetype == SPACE_IMAGE) {
SpaceImage *sima = sa->spacedata.first;
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
ED_uvedit_center_from_pivot(sima, scene, view_layer, r_center, sima->around);
ED_uvedit_center_from_pivot_ex(sima, scene, view_layer, r_center, sima->around, &has_select);
}
return has_select;
}
/**
@@ -366,11 +395,12 @@ static void gizmo2d_xform_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
GizmoGroup2D *ggd = gzgroup->customdata;
float origin[3];
bool has_select;
if (ggd->no_cage) {
gizmo2d_calc_center(C, origin);
has_select = gizmo2d_calc_center(C, origin);
}
else {
gizmo2d_calc_bounds(C, origin, ggd->min, ggd->max);
has_select = gizmo2d_calc_bounds(C, origin, ggd->min, ggd->max);
}
copy_v2_v2(ggd->origin, origin);
bool show_cage = !ggd->no_cage && !equals_v2v2(ggd->min, ggd->max);
@@ -385,58 +415,66 @@ static void gizmo2d_xform_refresh(const bContext *C, wmGizmoGroup *gzgroup)
}
}
if (show_cage) {
ggd->cage->flag &= ~WM_GIZMO_HIDDEN;
if (has_select == false) {
for (int i = 0; i < ARRAY_SIZE(ggd->translate_xy); i++) {
wmGizmo *gz = ggd->translate_xy[i];
gz->flag |= WM_GIZMO_HIDDEN;
ggd->translate_xy[i]->flag |= WM_GIZMO_HIDDEN;
}
ggd->cage->flag |= WM_GIZMO_HIDDEN;
}
else {
ggd->cage->flag |= WM_GIZMO_HIDDEN;
for (int i = 0; i < ARRAY_SIZE(ggd->translate_xy); i++) {
wmGizmo *gz = ggd->translate_xy[i];
gz->flag &= ~WM_GIZMO_HIDDEN;
if (show_cage) {
ggd->cage->flag &= ~WM_GIZMO_HIDDEN;
for (int i = 0; i < ARRAY_SIZE(ggd->translate_xy); i++) {
wmGizmo *gz = ggd->translate_xy[i];
gz->flag |= WM_GIZMO_HIDDEN;
}
}
else {
ggd->cage->flag |= WM_GIZMO_HIDDEN;
for (int i = 0; i < ARRAY_SIZE(ggd->translate_xy); i++) {
wmGizmo *gz = ggd->translate_xy[i];
gz->flag &= ~WM_GIZMO_HIDDEN;
}
}
}
if (show_cage) {
wmGizmoOpElem *gzop;
float mid[2];
const float *min = ggd->min;
const float *max = ggd->max;
mid_v2_v2v2(mid, min, max);
if (show_cage) {
wmGizmoOpElem *gzop;
float mid[2];
const float *min = ggd->min;
const float *max = ggd->max;
mid_v2_v2v2(mid, min, max);
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X);
PropertyRNA *prop_center_override = RNA_struct_find_property(&gzop->ptr, "center_override");
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){max[0], mid[1], 0.0f});
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X);
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){min[0], mid[1], 0.0f});
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y);
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){mid[0], max[1], 0.0f});
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y);
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){mid[0], min[1], 0.0f});
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X);
PropertyRNA *prop_center_override = RNA_struct_find_property(&gzop->ptr, "center_override");
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){max[0], mid[1], 0.0f});
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X);
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){min[0], mid[1], 0.0f});
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_Y);
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){mid[0], max[1], 0.0f});
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_Y);
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){mid[0], min[1], 0.0f});
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y);
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){max[0], max[1], 0.0f});
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y);
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){max[0], min[1], 0.0f});
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y);
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){min[0], max[1], 0.0f});
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y);
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){min[0], min[1], 0.0f});
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MIN_Y);
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){max[0], max[1], 0.0f});
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MIN_X_MAX_Y);
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){max[0], min[1], 0.0f});
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MIN_Y);
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){min[0], max[1], 0.0f});
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_SCALE_MAX_X_MAX_Y);
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){min[0], min[1], 0.0f});
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_ROTATE);
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){mid[0], mid[1], 0.0f});
gzop = WM_gizmo_operator_get(ggd->cage, ED_GIZMO_CAGE2D_PART_ROTATE);
RNA_property_float_set_array(
&gzop->ptr, prop_center_override, (float[3]){mid[0], mid[1], 0.0f});
}
}
}
@@ -460,50 +498,6 @@ static void gizmo2d_xform_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
ggd->cage->matrix_offset[1][1] = (ggd->max[1] - ggd->min[1]);
}
/* TODO (Julian)
* - Called on every redraw, better to do a more simple poll and check for selection in _refresh
* - UV editing only, could be expanded for other things.
*/
static bool gizmo2d_xform_poll(const bContext *C, wmGizmoGroupType *gzgt)
{
if (!ED_gizmo_poll_or_unlink_delayed_from_tool(C, gzgt)) {
return false;
}
if ((U.gizmo_flag & USER_GIZMO_DRAW) == 0) {
return false;
}
SpaceImage *sima = CTX_wm_space_image(C);
Object *obedit = CTX_data_edit_object(C);
if (ED_space_image_show_uvedit(sima, obedit)) {
Image *ima = ED_space_image(sima);
Scene *scene = CTX_data_scene(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BMFace *efa;
BMLoop *l;
BMIter iter, liter;
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
/* check if there's a selected poly */
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
continue;
}
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
return true;
}
}
}
}
return false;
}
static void gizmo2d_xform_no_cage_message_subscribe(const struct bContext *C,
struct wmGizmoGroup *gzgroup,
struct wmMsgBus *mbus)
@@ -516,7 +510,7 @@ static void gizmo2d_xform_no_cage_message_subscribe(const struct bContext *C,
void ED_widgetgroup_gizmo2d_xform_callbacks_set(wmGizmoGroupType *gzgt)
{
gzgt->poll = gizmo2d_xform_poll;
gzgt->poll = gizmo2d_generic_poll;
gzgt->setup = gizmo2d_xform_setup;
gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
gzgt->refresh = gizmo2d_xform_refresh;
@@ -564,8 +558,19 @@ static void gizmo2d_resize_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
GizmoGroup_Resize2D *ggd = gzgroup->customdata;
float origin[3];
gizmo2d_calc_center(C, origin);
copy_v2_v2(ggd->origin, origin);
const bool has_select = gizmo2d_calc_center(C, origin);
if (has_select == false) {
for (int i = 0; i < ARRAY_SIZE(ggd->gizmo_xy); i++) {
ggd->gizmo_xy[i]->flag |= WM_GIZMO_HIDDEN;
}
}
else {
for (int i = 0; i < ARRAY_SIZE(ggd->gizmo_xy); i++) {
ggd->gizmo_xy[i]->flag &= ~WM_GIZMO_HIDDEN;
}
copy_v2_v2(ggd->origin, origin);
}
}
static void gizmo2d_resize_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
@@ -592,11 +597,6 @@ static void gizmo2d_resize_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup
}
}
static bool gizmo2d_resize_poll(const bContext *C, wmGizmoGroupType *gzgt)
{
return gizmo2d_xform_poll(C, gzgt);
}
static void gizmo2d_resize_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
@@ -666,7 +666,7 @@ static void gizmo2d_resize_message_subscribe(const struct bContext *C,
void ED_widgetgroup_gizmo2d_resize_callbacks_set(wmGizmoGroupType *gzgt)
{
gzgt->poll = gizmo2d_resize_poll;
gzgt->poll = gizmo2d_generic_poll;
gzgt->setup = gizmo2d_resize_setup;
gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
gzgt->refresh = gizmo2d_resize_refresh;
@@ -705,8 +705,15 @@ static void gizmo2d_rotate_refresh(const bContext *C, wmGizmoGroup *gzgroup)
{
GizmoGroup_Rotate2D *ggd = gzgroup->customdata;
float origin[3];
gizmo2d_calc_center(C, origin);
copy_v2_v2(ggd->origin, origin);
const bool has_select = gizmo2d_calc_center(C, origin);
if (has_select == false) {
ggd->gizmo->flag |= WM_GIZMO_HIDDEN;
}
else {
ggd->gizmo->flag &= ~WM_GIZMO_HIDDEN;
copy_v2_v2(ggd->origin, origin);
}
}
static void gizmo2d_rotate_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup)
@@ -731,11 +738,6 @@ static void gizmo2d_rotate_draw_prepare(const bContext *C, wmGizmoGroup *gzgroup
WM_gizmo_set_matrix_location(gz, origin);
}
static bool gizmo2d_rotate_poll(const bContext *C, wmGizmoGroupType *gzgt)
{
return gizmo2d_xform_poll(C, gzgt);
}
static void gizmo2d_rotate_setup(const bContext *UNUSED(C), wmGizmoGroup *gzgroup)
{
@@ -780,7 +782,7 @@ static void gizmo2d_rotate_message_subscribe(const struct bContext *C,
void ED_widgetgroup_gizmo2d_rotate_callbacks_set(wmGizmoGroupType *gzgt)
{
gzgt->poll = gizmo2d_rotate_poll;
gzgt->poll = gizmo2d_generic_poll;
gzgt->setup = gizmo2d_rotate_setup;
gzgt->setup_keymap = WM_gizmogroup_setup_keymap_generic_maybe_drag;
gzgt->refresh = gizmo2d_rotate_refresh;

View File

@@ -755,14 +755,25 @@ bool ED_uvedit_center_multi(const Scene *scene,
return changed;
}
bool ED_uvedit_center_from_pivot(
SpaceImage *sima, Scene *scene, ViewLayer *view_layer, float r_center[2], char mode)
bool ED_uvedit_center_from_pivot_ex(SpaceImage *sima,
Scene *scene,
ViewLayer *view_layer,
float r_center[2],
char mode,
bool *r_has_select)
{
bool changed = false;
switch (mode) {
case V3D_AROUND_CURSOR: {
copy_v2_v2(r_center, sima->cursor);
changed = true;
if (r_has_select != NULL) {
uint objects_len = 0;
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data_with_uvs(
view_layer, ((View3D *)NULL), &objects_len);
*r_has_select = uv_select_is_any_selected_multi(scene, sima->image, objects, objects_len);
MEM_freeN(objects);
}
break;
}
default: {
@@ -771,12 +782,21 @@ bool ED_uvedit_center_from_pivot(
view_layer, ((View3D *)NULL), &objects_len);
changed = ED_uvedit_center_multi(scene, sima->image, objects, objects_len, r_center, mode);
MEM_freeN(objects);
if (r_has_select != NULL) {
*r_has_select = changed;
}
break;
}
}
return changed;
}
bool ED_uvedit_center_from_pivot(
SpaceImage *sima, Scene *scene, ViewLayer *view_layer, float r_center[2], char mode)
{
return ED_uvedit_center_from_pivot_ex(sima, scene, view_layer, r_center, mode, NULL);
}
/** \} */
/* -------------------------------------------------------------------- */