Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/mask/mask_ops.c
| Show All 25 Lines | |||||
| #include "BLI_listbase.h" | #include "BLI_listbase.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BKE_context.h" | #include "BKE_context.h" | ||||
| #include "BKE_main.h" | #include "BKE_main.h" | ||||
| #include "BKE_mask.h" | #include "BKE_mask.h" | ||||
| #include "DEG_depsgraph.h" | #include "DEG_depsgraph.h" | ||||
| #include "DEG_depsgraph_query.h" | |||||
| #include "DNA_scene_types.h" | #include "DNA_scene_types.h" | ||||
| #include "DNA_mask_types.h" | #include "DNA_mask_types.h" | ||||
| #include "DNA_object_types.h" /* SELECT */ | #include "DNA_object_types.h" /* SELECT */ | ||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| #include "WM_types.h" | #include "WM_types.h" | ||||
| Show All 18 Lines | static void mask_point_scaled_handle(/*const*/ MaskSplinePoint *point, | ||||
| float handle[2]) | float handle[2]) | ||||
| { | { | ||||
| BKE_mask_point_handle(point, which_handle, handle); | BKE_mask_point_handle(point, which_handle, handle); | ||||
| handle[0] *= scalex; | handle[0] *= scalex; | ||||
| handle[1] *= scaley; | handle[1] *= scaley; | ||||
| } | } | ||||
| MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C, | MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C, | ||||
| Mask *mask, | Mask *mask_orig, | ||||
| const float normal_co[2], | const float normal_co[2], | ||||
| const float threshold, | const float threshold, | ||||
| MaskLayer **masklay_r, | MaskLayer **masklay_r, | ||||
| MaskSpline **spline_r, | MaskSpline **spline_r, | ||||
| eMaskWhichHandle *which_handle_r, | eMaskWhichHandle *which_handle_r, | ||||
| float *score) | float *score) | ||||
| { | { | ||||
| ScrArea *sa = CTX_wm_area(C); | ScrArea *sa = CTX_wm_area(C); | ||||
| ARegion *ar = CTX_wm_region(C); | ARegion *ar = CTX_wm_region(C); | ||||
| MaskLayer *masklay; | |||||
| MaskLayer *point_masklay = NULL; | MaskLayer *point_masklay = NULL; | ||||
| MaskSpline *point_spline = NULL; | MaskSpline *point_spline = NULL; | ||||
| MaskSplinePoint *point = NULL; | MaskSplinePoint *point = NULL; | ||||
| float co[2]; | float co[2]; | ||||
| const float threshold_sq = threshold * threshold; | const float threshold_sq = threshold * threshold; | ||||
| float len_sq = FLT_MAX, scalex, scaley; | float len_sq = FLT_MAX, scalex, scaley; | ||||
| eMaskWhichHandle which_handle = MASK_WHICH_HANDLE_NONE; | eMaskWhichHandle which_handle = MASK_WHICH_HANDLE_NONE; | ||||
| int width, height; | int width, height; | ||||
| Depsgraph *depsgraph = CTX_data_evaluated_depsgraph(C); | |||||
| Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id); | |||||
| ED_mask_get_size(sa, &width, &height); | ED_mask_get_size(sa, &width, &height); | ||||
| ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley); | ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley); | ||||
| co[0] = normal_co[0] * scalex; | co[0] = normal_co[0] * scalex; | ||||
| co[1] = normal_co[1] * scaley; | co[1] = normal_co[1] * scaley; | ||||
| for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { | for (MaskLayer *masklay_orig = mask_orig->masklayers.first, | ||||
| MaskSpline *spline; | *masklay_eval = mask_eval->masklayers.first; | ||||
| masklay_orig != NULL; | |||||
| masklay_orig = masklay_orig->next, masklay_eval = masklay_eval->next) { | |||||
| if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { | if (masklay_orig->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| for (spline = masklay->splines.first; spline; spline = spline->next) { | for (MaskSpline *spline_orig = masklay_orig->splines.first, | ||||
| MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); | *spline_eval = masklay_eval->splines.first; | ||||
| spline_orig != NULL; | |||||
| int i; | spline_orig = spline_orig->next, spline_eval = spline_eval->next) { | ||||
| MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline_eval); | |||||
| for (i = 0; i < spline->tot_point; i++) { | |||||
| MaskSplinePoint *cur_point = &spline->points[i]; | for (int i = 0; i < spline_orig->tot_point; i++) { | ||||
| MaskSplinePoint *cur_point_deform = &points_array[i]; | MaskSplinePoint *cur_point_orig = &spline_orig->points[i]; | ||||
| MaskSplinePoint *cur_point_deform_eval = &points_array[i]; | |||||
| eMaskWhichHandle cur_which_handle = MASK_WHICH_HANDLE_NONE; | eMaskWhichHandle cur_which_handle = MASK_WHICH_HANDLE_NONE; | ||||
| BezTriple *bezt = &cur_point_deform->bezt; | BezTriple *bezt = &cur_point_deform_eval->bezt; | ||||
| float cur_len_sq, vec[2]; | float cur_len_sq, vec[2]; | ||||
| vec[0] = bezt->vec[1][0] * scalex; | vec[0] = bezt->vec[1][0] * scalex; | ||||
| vec[1] = bezt->vec[1][1] * scaley; | vec[1] = bezt->vec[1][1] * scaley; | ||||
| cur_len_sq = len_squared_v2v2(co, vec); | cur_len_sq = len_squared_v2v2(co, vec); | ||||
| if (cur_len_sq < len_sq) { | if (cur_len_sq < len_sq) { | ||||
| point_spline = spline; | point_spline = spline_orig; | ||||
| point_masklay = masklay; | point_masklay = masklay_orig; | ||||
| point = cur_point; | point = cur_point_orig; | ||||
| len_sq = cur_len_sq; | len_sq = cur_len_sq; | ||||
| which_handle = MASK_WHICH_HANDLE_NONE; | which_handle = MASK_WHICH_HANDLE_NONE; | ||||
| } | } | ||||
| if (BKE_mask_point_handles_mode_get(cur_point_deform) == MASK_HANDLE_MODE_STICK) { | if (BKE_mask_point_handles_mode_get(cur_point_deform_eval) == MASK_HANDLE_MODE_STICK) { | ||||
| float handle[2]; | float handle[2]; | ||||
| mask_point_scaled_handle( | mask_point_scaled_handle( | ||||
| cur_point_deform, MASK_WHICH_HANDLE_STICK, scalex, scaley, handle); | cur_point_deform_eval, MASK_WHICH_HANDLE_STICK, scalex, scaley, handle); | ||||
| cur_len_sq = len_squared_v2v2(co, handle); | cur_len_sq = len_squared_v2v2(co, handle); | ||||
| cur_which_handle = MASK_WHICH_HANDLE_STICK; | cur_which_handle = MASK_WHICH_HANDLE_STICK; | ||||
| } | } | ||||
| else { | else { | ||||
| float handle_left[2], handle_right[2]; | float handle_left[2], handle_right[2]; | ||||
| float len_left_sq, len_right_sq; | float len_left_sq, len_right_sq; | ||||
| mask_point_scaled_handle( | mask_point_scaled_handle( | ||||
| cur_point_deform, MASK_WHICH_HANDLE_LEFT, scalex, scaley, handle_left); | cur_point_deform_eval, MASK_WHICH_HANDLE_LEFT, scalex, scaley, handle_left); | ||||
| mask_point_scaled_handle( | mask_point_scaled_handle( | ||||
| cur_point_deform, MASK_WHICH_HANDLE_RIGHT, scalex, scaley, handle_right); | cur_point_deform_eval, MASK_WHICH_HANDLE_RIGHT, scalex, scaley, handle_right); | ||||
| len_left_sq = len_squared_v2v2(co, handle_left); | len_left_sq = len_squared_v2v2(co, handle_left); | ||||
| len_right_sq = len_squared_v2v2(co, handle_right); | len_right_sq = len_squared_v2v2(co, handle_right); | ||||
| if (i == 0) { | if (i == 0) { | ||||
| if (len_left_sq <= len_right_sq) { | if (len_left_sq <= len_right_sq) { | ||||
| if (bezt->h1 != HD_VECT) { | if (bezt->h1 != HD_VECT) { | ||||
| cur_which_handle = MASK_WHICH_HANDLE_LEFT; | cur_which_handle = MASK_WHICH_HANDLE_LEFT; | ||||
| cur_len_sq = len_left_sq; | cur_len_sq = len_left_sq; | ||||
| Show All 14 Lines | for (MaskSpline *spline_orig = masklay_orig->splines.first, | ||||
| else if (bezt->h1 != HD_VECT) { | else if (bezt->h1 != HD_VECT) { | ||||
| cur_which_handle = MASK_WHICH_HANDLE_LEFT; | cur_which_handle = MASK_WHICH_HANDLE_LEFT; | ||||
| cur_len_sq = len_left_sq; | cur_len_sq = len_left_sq; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (cur_len_sq <= len_sq && cur_which_handle != MASK_WHICH_HANDLE_NONE) { | if (cur_len_sq <= len_sq && cur_which_handle != MASK_WHICH_HANDLE_NONE) { | ||||
| point_masklay = masklay; | point_masklay = masklay_orig; | ||||
| point_spline = spline; | point_spline = spline_orig; | ||||
| point = cur_point; | point = cur_point_orig; | ||||
| len_sq = cur_len_sq; | len_sq = cur_len_sq; | ||||
| which_handle = cur_which_handle; | which_handle = cur_which_handle; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (len_sq < threshold_sq) { | if (len_sq < threshold_sq) { | ||||
| Show All 27 Lines | MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C, | ||||
| if (which_handle_r) { | if (which_handle_r) { | ||||
| *which_handle_r = MASK_WHICH_HANDLE_NONE; | *which_handle_r = MASK_WHICH_HANDLE_NONE; | ||||
| } | } | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| bool ED_mask_feather_find_nearest(const bContext *C, | bool ED_mask_feather_find_nearest(const bContext *C, | ||||
| Mask *mask, | Mask *mask_orig, | ||||
| const float normal_co[2], | const float normal_co[2], | ||||
| const float threshold, | const float threshold, | ||||
| MaskLayer **masklay_r, | MaskLayer **masklay_r, | ||||
| MaskSpline **spline_r, | MaskSpline **spline_r, | ||||
| MaskSplinePoint **point_r, | MaskSplinePoint **point_r, | ||||
| MaskSplinePointUW **uw_r, | MaskSplinePointUW **uw_r, | ||||
| float *score) | float *score) | ||||
| { | { | ||||
| ScrArea *sa = CTX_wm_area(C); | ScrArea *sa = CTX_wm_area(C); | ||||
| ARegion *ar = CTX_wm_region(C); | ARegion *ar = CTX_wm_region(C); | ||||
| MaskLayer *masklay, *point_masklay = NULL; | MaskLayer *point_masklay = NULL; | ||||
| MaskSpline *point_spline = NULL; | MaskSpline *point_spline = NULL; | ||||
| MaskSplinePoint *point = NULL; | MaskSplinePoint *point = NULL; | ||||
| MaskSplinePointUW *uw = NULL; | MaskSplinePointUW *uw = NULL; | ||||
| const float threshold_sq = threshold * threshold; | const float threshold_sq = threshold * threshold; | ||||
| float len = FLT_MAX, co[2]; | float len = FLT_MAX, co[2]; | ||||
| float scalex, scaley; | float scalex, scaley; | ||||
| int width, height; | int width, height; | ||||
| Depsgraph *depsgraph = CTX_data_evaluated_depsgraph(C); | |||||
| Mask *mask_eval = (Mask *)DEG_get_evaluated_id(depsgraph, &mask_orig->id); | |||||
| ED_mask_get_size(sa, &width, &height); | ED_mask_get_size(sa, &width, &height); | ||||
| ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley); | ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley); | ||||
| co[0] = normal_co[0] * scalex; | co[0] = normal_co[0] * scalex; | ||||
| co[1] = normal_co[1] * scaley; | co[1] = normal_co[1] * scaley; | ||||
| for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { | for (MaskLayer *masklay_orig = mask_orig->masklayers.first, | ||||
| MaskSpline *spline; | *masklay_eval = mask_eval->masklayers.first; | ||||
| masklay_orig != NULL; | |||||
| for (spline = masklay->splines.first; spline; spline = spline->next) { | masklay_orig = masklay_orig->next, masklay_eval = masklay_eval->next) { | ||||
| for (MaskSpline *spline_orig = masklay_orig->splines.first, | |||||
| *spline_eval = masklay_eval->splines.first; | |||||
| spline_orig != NULL; | |||||
| spline_orig = spline_orig->next, spline_eval = spline_eval->next) { | |||||
| // MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); | // MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); | ||||
| int i, tot_feather_point; | int i, tot_feather_point; | ||||
| float(*feather_points)[2], (*fp)[2]; | float(*feather_points)[2], (*fp)[2]; | ||||
| if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { | if (masklay_orig->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point); | feather_points = fp = BKE_mask_spline_feather_points(spline_eval, &tot_feather_point); | ||||
| for (i = 0; i < spline->tot_point; i++) { | for (i = 0; i < spline_orig->tot_point; i++) { | ||||
| int j; | int j; | ||||
| MaskSplinePoint *cur_point = &spline->points[i]; | MaskSplinePoint *cur_point_orig = &spline_orig->points[i]; | ||||
| MaskSplinePoint *cur_point_eval = &spline_eval->points[i]; | |||||
| for (j = 0; j <= cur_point->tot_uw; j++) { | for (j = 0; j <= cur_point_eval->tot_uw; j++) { | ||||
| float cur_len_sq, vec[2]; | float cur_len_sq, vec[2]; | ||||
| vec[0] = (*fp)[0] * scalex; | vec[0] = (*fp)[0] * scalex; | ||||
| vec[1] = (*fp)[1] * scaley; | vec[1] = (*fp)[1] * scaley; | ||||
| cur_len_sq = len_squared_v2v2(vec, co); | cur_len_sq = len_squared_v2v2(vec, co); | ||||
| if (point == NULL || cur_len_sq < len) { | if (point == NULL || cur_len_sq < len) { | ||||
| if (j == 0) { | if (j == 0) { | ||||
| uw = NULL; | uw = NULL; | ||||
| } | } | ||||
| else { | else { | ||||
| uw = &cur_point->uw[j - 1]; | uw = &cur_point_eval->uw[j - 1]; | ||||
| } | } | ||||
| point_masklay = masklay; | point_masklay = masklay_orig; | ||||
| point_spline = spline; | point_spline = spline_orig; | ||||
| point = cur_point; | point = cur_point_orig; | ||||
| len = cur_len_sq; | len = cur_len_sq; | ||||
| } | } | ||||
| fp++; | fp++; | ||||
| } | } | ||||
| } | } | ||||
| MEM_freeN(feather_points); | MEM_freeN(feather_points); | ||||
| ▲ Show 20 Lines • Show All 1,353 Lines • ▼ Show 20 Lines | else { | ||||
| point->uw = new_uw; | point->uw = new_uw; | ||||
| point->tot_uw = count; | point->tot_uw = count; | ||||
| } | } | ||||
| } | } | ||||
| static int delete_exec(bContext *C, wmOperator *UNUSED(op)) | static int delete_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | |||||
| Mask *mask = CTX_data_edit_mask(C); | Mask *mask = CTX_data_edit_mask(C); | ||||
| MaskLayer *masklay; | MaskLayer *masklay; | ||||
| bool changed = false; | bool changed = false; | ||||
| for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { | for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { | ||||
| MaskSpline *spline; | MaskSpline *spline; | ||||
| int mask_layer_shape_ofs = 0; | int mask_layer_shape_ofs = 0; | ||||
| ▲ Show 20 Lines • Show All 78 Lines • ▼ Show 20 Lines | if (BLI_listbase_is_empty(&masklay->splines)) { | ||||
| BKE_mask_layer_free_shapes(masklay); | BKE_mask_layer_free_shapes(masklay); | ||||
| } | } | ||||
| } | } | ||||
| if (!changed) { | if (!changed) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| /* TODO: only update edited splines */ | DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY); | ||||
| BKE_mask_update_display(mask, CFRA); | |||||
| WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); | WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void MASK_OT_delete(wmOperatorType *ot) | void MASK_OT_delete(wmOperatorType *ot) | ||||
| { | { | ||||
| Show All 40 Lines | for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { | ||||
| if (changed_layer) { | if (changed_layer) { | ||||
| if (IS_AUTOKEY_ON(scene)) { | if (IS_AUTOKEY_ON(scene)) { | ||||
| ED_mask_layer_shape_auto_key(masklay, CFRA); | ED_mask_layer_shape_auto_key(masklay, CFRA); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (changed) { | if (changed) { | ||||
| /* TODO: only update this spline */ | DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY); | ||||
| BKE_mask_update_display(mask, CFRA); | |||||
| WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); | WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); | ||||
| WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); | WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| ▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { | ||||
| if (changed_layer) { | if (changed_layer) { | ||||
| if (IS_AUTOKEY_ON(scene)) { | if (IS_AUTOKEY_ON(scene)) { | ||||
| ED_mask_layer_shape_auto_key(masklay, CFRA); | ED_mask_layer_shape_auto_key(masklay, CFRA); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (changed) { | if (changed) { | ||||
| /* TODO: only update this spline */ | DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY); | ||||
| BKE_mask_update_display(mask, CFRA); | |||||
| WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); | WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); | ||||
| WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); | WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| ▲ Show 20 Lines • Show All 209 Lines • ▼ Show 20 Lines | void MASK_OT_hide_view_set(wmOperatorType *ot) | ||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ||||
| RNA_def_boolean( | RNA_def_boolean( | ||||
| ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected layers"); | ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected layers"); | ||||
| } | } | ||||
| static int mask_feather_weight_clear_exec(bContext *C, wmOperator *UNUSED(op)) | static int mask_feather_weight_clear_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | |||||
| Mask *mask = CTX_data_edit_mask(C); | Mask *mask = CTX_data_edit_mask(C); | ||||
| MaskLayer *masklay; | MaskLayer *masklay; | ||||
| bool changed = false; | bool changed = false; | ||||
| int i; | int i; | ||||
| for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { | for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { | ||||
| MaskSpline *spline; | MaskSpline *spline; | ||||
| Show All 10 Lines | for (spline = masklay->splines.first; spline; spline = spline->next) { | ||||
| bezt->weight = 0.0f; | bezt->weight = 0.0f; | ||||
| changed = true; | changed = true; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (changed) { | if (changed) { | ||||
| /* TODO: only update edited splines */ | DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY); | ||||
| BKE_mask_update_display(mask, CFRA); | |||||
| WM_event_add_notifier(C, NC_MASK | ND_DRAW, mask); | WM_event_add_notifier(C, NC_MASK | ND_DRAW, mask); | ||||
| DEG_id_tag_update(&mask->id, 0); | DEG_id_tag_update(&mask->id, 0); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| else { | else { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| ▲ Show 20 Lines • Show All 95 Lines • ▼ Show 20 Lines | RNA_def_enum(ot->srna, | ||||
| "Direction", | "Direction", | ||||
| "Direction to move the active layer"); | "Direction to move the active layer"); | ||||
| } | } | ||||
| /******************** duplicate *********************/ | /******************** duplicate *********************/ | ||||
| static int mask_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) | static int mask_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | |||||
| Mask *mask = CTX_data_edit_mask(C); | Mask *mask = CTX_data_edit_mask(C); | ||||
| MaskLayer *mask_layer; | MaskLayer *mask_layer; | ||||
| for (mask_layer = mask->masklayers.first; mask_layer; mask_layer = mask_layer->next) { | for (mask_layer = mask->masklayers.first; mask_layer; mask_layer = mask_layer->next) { | ||||
| MaskSpline *spline; | MaskSpline *spline; | ||||
| for (spline = mask_layer->splines.last; spline; spline = spline->prev) { | for (spline = mask_layer->splines.last; spline; spline = spline->prev) { | ||||
| MaskSplinePoint *point = spline->points; | MaskSplinePoint *point = spline->points; | ||||
| ▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | for (spline = mask_layer->splines.last; spline; spline = spline->prev) { | ||||
| mask_layer->act_spline = new_spline; | mask_layer->act_spline = new_spline; | ||||
| } | } | ||||
| i++; | i++; | ||||
| point++; | point++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* TODO: only update edited splines */ | DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY); | ||||
| BKE_mask_update_display(mask, CFRA); | |||||
| WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); | WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void MASK_OT_duplicate(wmOperatorType *ot) | void MASK_OT_duplicate(wmOperatorType *ot) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | if (ED_maskedit_mask_poll(C)) { | ||||
| return BKE_mask_clipboard_is_empty() == false; | return BKE_mask_clipboard_is_empty() == false; | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| static int paste_splines_exec(bContext *C, wmOperator *UNUSED(op)) | static int paste_splines_exec(bContext *C, wmOperator *UNUSED(op)) | ||||
| { | { | ||||
| Scene *scene = CTX_data_scene(C); | |||||
| Mask *mask = CTX_data_edit_mask(C); | Mask *mask = CTX_data_edit_mask(C); | ||||
| MaskLayer *mask_layer = BKE_mask_layer_active(mask); | MaskLayer *mask_layer = BKE_mask_layer_active(mask); | ||||
| if (mask_layer == NULL) { | if (mask_layer == NULL) { | ||||
| mask_layer = BKE_mask_layer_new(mask, ""); | mask_layer = BKE_mask_layer_new(mask, ""); | ||||
| } | } | ||||
| BKE_mask_clipboard_paste_to_layer(CTX_data_main(C), mask_layer); | BKE_mask_clipboard_paste_to_layer(CTX_data_main(C), mask_layer); | ||||
| /* TODO: only update edited splines */ | DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY); | ||||
| BKE_mask_update_display(mask, CFRA); | |||||
| WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); | WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void MASK_OT_paste_splines(wmOperatorType *ot) | void MASK_OT_paste_splines(wmOperatorType *ot) | ||||
| { | { | ||||
| Show All 12 Lines | |||||