void BKE_mask_layer_evaluate_deform(MaskLayer *masklay, const float ctime) { BKE_mask_layer_calc_handles(masklay); for (MaskSpline *spline = masklay->splines.first; spline != NULL; spline = spline->next) { bool need_handle_recalc = false; BKE_mask_spline_ensure_deform(spline); for (int i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; MaskSplinePoint *point_deform = &spline->points_deform[i]; BKE_mask_point_free(point_deform); *point_deform = *point; point_deform->uw = point->uw ? MEM_dupallocN(point->uw) : NULL; mask_evaluate_apply_point_parent(point_deform, ctime); if (ELEM(point->bezt.h1, HD_AUTO, HD_VECT)) { need_handle_recalc = true; } } /* if the spline has auto or vector handles, these need to be * recalculated after deformation. */ if (need_handle_recalc) { for (int i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point_deform = &spline->points_deform[i]; if (ELEM(point_deform->bezt.h1, HD_AUTO, HD_VECT)) { BKE_mask_calc_handle_point(spline, point_deform); } } } /* end extra calc handles loop */ } }
static int delete_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene = CTX_data_scene(C); Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; bool changed = false; for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; int mask_layer_shape_ofs = 0; if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } spline = masklay->splines.first; while (spline) { const int tot_point_orig = spline->tot_point; int i, count = 0; MaskSpline *next_spline = spline->next; /* count unselected points */ for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; if (!MASKPOINT_ISSEL_ANY(point)) count++; } if (count == 0) { /* delete the whole spline */ BLI_remlink(&masklay->splines, spline); BKE_mask_spline_free(spline); if (spline == masklay->act_spline) { masklay->act_spline = NULL; masklay->act_point = NULL; } BKE_mask_layer_shape_changed_remove(masklay, mask_layer_shape_ofs, tot_point_orig); } else { MaskSplinePoint *new_points; int j; new_points = MEM_callocN(count * sizeof(MaskSplinePoint), "deleteMaskPoints"); for (i = 0, j = 0; i < tot_point_orig; i++) { MaskSplinePoint *point = &spline->points[i]; if (!MASKPOINT_ISSEL_ANY(point)) { if (point == masklay->act_point) masklay->act_point = &new_points[j]; delete_feather_points(point); new_points[j] = *point; j++; } else { if (point == masklay->act_point) masklay->act_point = NULL; BKE_mask_point_free(point); spline->tot_point--; BKE_mask_layer_shape_changed_remove(masklay, mask_layer_shape_ofs + j, 1); } } mask_layer_shape_ofs += spline->tot_point; MEM_freeN(spline->points); spline->points = new_points; ED_mask_select_flush_all(mask); } changed = true; spline = next_spline; } /* not essential but confuses users when there are keys with no data! * assume if they delete all data from the layer they also dont care about keys */ if (masklay->splines.first == NULL) { BKE_mask_layer_free_shapes(masklay); } } if (!changed) { return OPERATOR_CANCELLED; } /* TODO: only update edited splines */ BKE_mask_update_display(mask, CFRA); WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return OPERATOR_FINISHED; }