From 45f30543db3c8f6898668907aa8088d434394be6 Mon Sep 17 00:00:00 2001 From: Philipp Oeser Date: Fri, 8 Apr 2022 13:25:41 +0200 Subject: Fix T97135: Fix selection issues with parented masks in the MCE Box, Circle and Lasso select were not taking into account if a mask(point) was parented; selection was only succeeding in the original place. Now check coordinates from evaluated mask (points) instead while setting selection flags and DEG tagging still happens on the original ID. Maniphest Tasks: T97135 Differential Revision: https://developer.blender.org/D14651 --- source/blender/editors/mask/mask_select.c | 93 ++++++++++++++++++++----------- 1 file changed, 60 insertions(+), 33 deletions(-) (limited to 'source/blender/editors/mask') diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index 29cd593ce7f..e3c3f1c38a0 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -16,6 +16,9 @@ #include "BKE_context.h" #include "BKE_mask.h" +#include "DEG_depsgraph.h" +#include "DEG_depsgraph_query.h" + #include "DNA_mask_types.h" #include "WM_api.h" @@ -427,7 +430,9 @@ static int box_select_exec(bContext *C, wmOperator *op) ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); - Mask *mask = CTX_data_edit_mask(C); + Mask *mask_orig = CTX_data_edit_mask(C); + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id); rcti rect; rctf rectf; @@ -436,7 +441,7 @@ static int box_select_exec(bContext *C, wmOperator *op) const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode"); const bool select = (sel_op != SEL_OP_SUB); if (SEL_OP_USE_PRE_DESELECT(sel_op)) { - ED_mask_select_toggle_all(mask, SEL_DESELECT); + ED_mask_select_toggle_all(mask_orig, SEL_DESELECT); changed = true; } @@ -447,16 +452,22 @@ static int box_select_exec(bContext *C, wmOperator *op) ED_mask_point_pos(area, region, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); /* do actual selection */ - LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) { - if (mask_layer->visibility_flag & (MASK_HIDE_VIEW | MASK_HIDE_SELECT)) { + for (MaskLayer *mask_layer_orig = mask_orig->masklayers.first, + *mask_layer_eval = mask_eval->masklayers.first; + mask_layer_orig != NULL; + mask_layer_orig = mask_layer_orig->next, mask_layer_eval = mask_layer_eval->next) { + if (mask_layer_orig->visibility_flag & (MASK_HIDE_VIEW | MASK_HIDE_SELECT)) { continue; } + for (MaskSpline *spline_orig = mask_layer_orig->splines.first, + *spline_eval = mask_layer_eval->splines.first; + spline_orig != NULL; + spline_orig = spline_orig->next, spline_eval = spline_eval->next) { - LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) { - MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline_eval); - for (int i = 0; i < spline->tot_point; i++) { - MaskSplinePoint *point = &spline->points[i]; + for (int i = 0; i < spline_orig->tot_point; i++) { + MaskSplinePoint *point = &spline_orig->points[i]; MaskSplinePoint *point_deform = &points_array[i]; /* TODO: handles? */ @@ -471,10 +482,10 @@ static int box_select_exec(bContext *C, wmOperator *op) } if (changed) { - ED_mask_select_flush_all(mask); + ED_mask_select_flush_all(mask_orig); - DEG_id_tag_update(&mask->id, ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + DEG_id_tag_update(&mask_orig->id, ID_RECALC_SELECT); + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask_orig); return OPERATOR_FINISHED; } @@ -517,14 +528,16 @@ static bool do_lasso_select_mask(bContext *C, ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); - Mask *mask = CTX_data_edit_mask(C); + Mask *mask_orig = CTX_data_edit_mask(C); + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id); rcti rect; bool changed = false; const bool select = (sel_op != SEL_OP_SUB); if (SEL_OP_USE_PRE_DESELECT(sel_op)) { - ED_mask_select_toggle_all(mask, SEL_DESELECT); + ED_mask_select_toggle_all(mask_orig, SEL_DESELECT); changed = true; } @@ -532,16 +545,22 @@ static bool do_lasso_select_mask(bContext *C, BLI_lasso_boundbox(&rect, mcoords, mcoords_len); /* do actual selection */ - LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) { - if (mask_layer->visibility_flag & (MASK_HIDE_VIEW | MASK_HIDE_SELECT)) { + for (MaskLayer *mask_layer_orig = mask_orig->masklayers.first, + *mask_layer_eval = mask_eval->masklayers.first; + mask_layer_orig != NULL; + mask_layer_orig = mask_layer_orig->next, mask_layer_eval = mask_layer_eval->next) { + if (mask_layer_orig->visibility_flag & (MASK_HIDE_VIEW | MASK_HIDE_SELECT)) { continue; } + for (MaskSpline *spline_orig = mask_layer_orig->splines.first, + *spline_eval = mask_layer_eval->splines.first; + spline_orig != NULL; + spline_orig = spline_orig->next, spline_eval = spline_eval->next) { - LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) { - MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline_eval); - for (int i = 0; i < spline->tot_point; i++) { - MaskSplinePoint *point = &spline->points[i]; + for (int i = 0; i < spline_orig->tot_point; i++) { + MaskSplinePoint *point = &spline_orig->points[i]; MaskSplinePoint *point_deform = &points_array[i]; /* TODO: handles? */ @@ -572,10 +591,10 @@ static bool do_lasso_select_mask(bContext *C, } if (changed) { - ED_mask_select_flush_all(mask); + ED_mask_select_flush_all(mask_orig); - DEG_id_tag_update(&mask->id, ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + DEG_id_tag_update(&mask_orig->id, ID_RECALC_SELECT); + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask_orig); } return changed; @@ -643,7 +662,9 @@ static int circle_select_exec(bContext *C, wmOperator *op) ScrArea *area = CTX_wm_area(C); ARegion *region = CTX_wm_region(C); - Mask *mask = CTX_data_edit_mask(C); + Mask *mask_orig = CTX_data_edit_mask(C); + Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); + Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id); float zoomx, zoomy, offset[2], ellipse[2]; int width, height; @@ -668,21 +689,27 @@ static int circle_select_exec(bContext *C, wmOperator *op) WM_gesture_is_modal_first(op->customdata)); const bool select = (sel_op != SEL_OP_SUB); if (SEL_OP_USE_PRE_DESELECT(sel_op)) { - ED_mask_select_toggle_all(mask, SEL_DESELECT); + ED_mask_select_toggle_all(mask_orig, SEL_DESELECT); changed = true; } /* do actual selection */ - LISTBASE_FOREACH (MaskLayer *, mask_layer, &mask->masklayers) { - if (mask_layer->visibility_flag & (MASK_HIDE_VIEW | MASK_HIDE_SELECT)) { + for (MaskLayer *mask_layer_orig = mask_orig->masklayers.first, + *mask_layer_eval = mask_eval->masklayers.first; + mask_layer_orig != NULL; + mask_layer_orig = mask_layer_orig->next, mask_layer_eval = mask_layer_eval->next) { + if (mask_layer_orig->visibility_flag & (MASK_HIDE_VIEW | MASK_HIDE_SELECT)) { continue; } + for (MaskSpline *spline_orig = mask_layer_orig->splines.first, + *spline_eval = mask_layer_eval->splines.first; + spline_orig != NULL; + spline_orig = spline_orig->next, spline_eval = spline_eval->next) { - LISTBASE_FOREACH (MaskSpline *, spline, &mask_layer->splines) { - MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline_eval); - for (int i = 0; i < spline->tot_point; i++) { - MaskSplinePoint *point = &spline->points[i]; + for (int i = 0; i < spline_orig->tot_point; i++) { + MaskSplinePoint *point = &spline_orig->points[i]; MaskSplinePoint *point_deform = &points_array[i]; if (mask_spline_point_inside_ellipse(&point_deform->bezt, offset, ellipse)) { @@ -696,10 +723,10 @@ static int circle_select_exec(bContext *C, wmOperator *op) } if (changed) { - ED_mask_select_flush_all(mask); + ED_mask_select_flush_all(mask_orig); - DEG_id_tag_update(&mask->id, ID_RECALC_SELECT); - WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); + DEG_id_tag_update(&mask_orig->id, ID_RECALC_SELECT); + WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask_orig); return OPERATOR_FINISHED; } -- cgit v1.2.3