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
This commit is contained in:
Philipp Oeser 2022-04-08 13:25:41 +02:00
parent ad245a25e2
commit 45f30543db
Notes: blender-bot 2023-02-14 07:30:31 +01:00
Referenced by issue #88449: Blender LTS: Maintenance Task 2.93
Referenced by issue #88449, Blender LTS: Maintenance Task 2.93
Referenced by issue #97135, Node mask selection does not take in consideration the parenting with the markers
1 changed files with 60 additions and 33 deletions

View File

@ -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;
}