Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/mask/mask_add.c
| Show All 23 Lines | |||||
| #include "MEM_guardedalloc.h" | #include "MEM_guardedalloc.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BKE_context.h" | #include "BKE_context.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_screen_types.h" | #include "DNA_screen_types.h" | ||||
| #include "DNA_mask_types.h" | #include "DNA_mask_types.h" | ||||
| #include "WM_api.h" | #include "WM_api.h" | ||||
| #include "WM_types.h" | #include "WM_types.h" | ||||
| #include "ED_select_utils.h" | #include "ED_select_utils.h" | ||||
| #include "ED_mask.h" /* own include */ | #include "ED_mask.h" /* own include */ | ||||
| #include "ED_screen.h" | #include "ED_screen.h" | ||||
| #include "RNA_access.h" | #include "RNA_access.h" | ||||
| #include "RNA_define.h" | #include "RNA_define.h" | ||||
| #include "mask_intern.h" /* own include */ | #include "mask_intern.h" /* own include */ | ||||
| bool ED_mask_find_nearest_diff_point(const bContext *C, | bool ED_mask_find_nearest_diff_point(const bContext *C, | ||||
| struct Mask *mask, | struct Mask *mask_orig, | ||||
| const float normal_co[2], | const float normal_co[2], | ||||
| int threshold, | int threshold, | ||||
| bool feather, | bool feather, | ||||
| float tangent[2], | float tangent[2], | ||||
| const bool use_deform, | const bool use_deform, | ||||
| const bool use_project, | const bool use_project, | ||||
| MaskLayer **masklay_r, | MaskLayer **masklay_r, | ||||
| MaskSpline **spline_r, | MaskSpline **spline_r, | ||||
| MaskSplinePoint **point_r, | MaskSplinePoint **point_r, | ||||
| float *u_r, | float *u_r, | ||||
| float *score_r) | float *score_r) | ||||
| { | { | ||||
| 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; | MaskLayer *point_masklay; | ||||
| MaskSpline *point_spline; | MaskSpline *point_spline; | ||||
| MaskSplinePoint *point = NULL; | MaskSplinePoint *point = NULL; | ||||
| float dist_best_sq = FLT_MAX, co[2]; | float dist_best_sq = FLT_MAX, co[2]; | ||||
| int width, height; | int width, height; | ||||
| float u = 0.0f; | float u = 0.0f; | ||||
| float scalex, scaley; | float scalex, scaley; | ||||
| 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; | |||||
| if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { | masklay_orig = masklay_orig->next, masklay_eval = masklay_eval->next) { | ||||
| 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, | ||||
| *spline_eval = masklay_eval->splines.first; | |||||
| spline_orig != NULL; | |||||
| spline_orig = spline_orig->next, spline_eval = spline_eval->next) { | |||||
| int i; | int i; | ||||
| MaskSplinePoint *cur_point; | MaskSplinePoint *cur_point_eval; | ||||
| for (i = 0, cur_point = use_deform ? spline->points_deform : spline->points; | for (i = 0, cur_point_eval = use_deform ? spline_eval->points_deform : spline_eval->points; | ||||
| i < spline->tot_point; | i < spline_eval->tot_point; | ||||
| i++, cur_point++) { | i++, cur_point_eval++) { | ||||
| float *diff_points; | |||||
| unsigned int tot_diff_point; | unsigned int tot_diff_point; | ||||
| float *diff_points = BKE_mask_point_segment_diff( | |||||
| diff_points = BKE_mask_point_segment_diff( | spline_eval, cur_point_eval, width, height, &tot_diff_point); | ||||
| spline, cur_point, width, height, &tot_diff_point); | |||||
| if (diff_points) { | if (diff_points) { | ||||
| int j, tot_point; | int j, tot_point; | ||||
| unsigned int tot_feather_point; | unsigned int tot_feather_point; | ||||
| float *feather_points = NULL, *points; | float *feather_points = NULL, *points; | ||||
| if (feather) { | if (feather) { | ||||
| feather_points = BKE_mask_point_segment_feather_diff( | feather_points = BKE_mask_point_segment_feather_diff( | ||||
| spline, cur_point, width, height, &tot_feather_point); | spline_eval, cur_point_eval, width, height, &tot_feather_point); | ||||
| points = feather_points; | points = feather_points; | ||||
| tot_point = tot_feather_point; | tot_point = tot_feather_point; | ||||
| } | } | ||||
| else { | else { | ||||
| points = diff_points; | points = diff_points; | ||||
| tot_point = tot_diff_point; | tot_point = tot_diff_point; | ||||
| } | } | ||||
| Show All 9 Lines | for (MaskSpline *spline_orig = masklay_orig->splines.first, | ||||
| dist_sq = dist_squared_to_line_segment_v2(co, a, b); | dist_sq = dist_squared_to_line_segment_v2(co, a, b); | ||||
| if (dist_sq < dist_best_sq) { | if (dist_sq < dist_best_sq) { | ||||
| if (tangent) { | if (tangent) { | ||||
| sub_v2_v2v2(tangent, &diff_points[2 * j + 2], &diff_points[2 * j]); | sub_v2_v2v2(tangent, &diff_points[2 * j + 2], &diff_points[2 * j]); | ||||
| } | } | ||||
| point_masklay = masklay; | point_masklay = masklay_orig; | ||||
| point_spline = spline; | point_spline = spline_orig; | ||||
| point = use_deform ? &spline->points[(cur_point - spline->points_deform)] : | point = use_deform ? | ||||
| cur_point; | &spline_orig->points[(cur_point_eval - spline_eval->points_deform)] : | ||||
| &spline_orig->points[(cur_point_eval - spline_eval->points)]; | |||||
| dist_best_sq = dist_sq; | dist_best_sq = dist_sq; | ||||
| u = (float)j / tot_point; | u = (float)j / tot_point; | ||||
| } | } | ||||
| } | } | ||||
| if (feather_points) { | if (feather_points != NULL) { | ||||
| MEM_freeN(feather_points); | MEM_freeN(feather_points); | ||||
| } | } | ||||
| MEM_freeN(diff_points); | MEM_freeN(diff_points); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (point && dist_best_sq < threshold) { | if (point && dist_best_sq < threshold) { | ||||
| if (masklay_r) { | if (masklay_r) { | ||||
| ▲ Show 20 Lines • Show All 421 Lines • ▼ Show 20 Lines | static bool add_vertex_new(const bContext *C, Mask *mask, MaskLayer *masklay, const float co[2]) | ||||
| WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); | WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); | ||||
| return true; | return true; | ||||
| } | } | ||||
| static int add_vertex_exec(bContext *C, wmOperator *op) | static int add_vertex_exec(bContext *C, wmOperator *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; | ||||
| float co[2]; | float co[2]; | ||||
| if (mask == NULL) { | if (mask == NULL) { | ||||
| /* if there's no active mask, create one */ | /* if there's no active mask, create one */ | ||||
| mask = ED_mask_new(C, NULL); | mask = ED_mask_new(C, NULL); | ||||
| Show All 29 Lines | if ((is_sta || is_end) && equals_v2v2(co, point->bezt.vec[1])) { | ||||
| MaskSplinePoint *point_other = is_end ? spline->points : | MaskSplinePoint *point_other = is_end ? spline->points : | ||||
| &spline->points[spline->tot_point - 1]; | &spline->points[spline->tot_point - 1]; | ||||
| spline->flag |= MASK_SPLINE_CYCLIC; | spline->flag |= MASK_SPLINE_CYCLIC; | ||||
| /* TODO, update keyframes in time */ | /* TODO, update keyframes in time */ | ||||
| BKE_mask_calc_handle_point_auto(spline, point, false); | BKE_mask_calc_handle_point_auto(spline, point, false); | ||||
| BKE_mask_calc_handle_point_auto(spline, point_other, false); | BKE_mask_calc_handle_point_auto(spline, point_other, false); | ||||
| /* 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 | NA_EDITED, mask); | WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| } | } | ||||
| if (!add_vertex_subdivide(C, mask, co)) { | if (!add_vertex_subdivide(C, mask, co)) { | ||||
| if (!add_vertex_extrude(C, mask, masklay, co)) { | if (!add_vertex_extrude(C, mask, masklay, co)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| if (!add_vertex_subdivide(C, mask, co)) { | if (!add_vertex_subdivide(C, mask, co)) { | ||||
| if (!add_vertex_new(C, mask, masklay, co)) { | if (!add_vertex_new(C, mask, masklay, co)) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* TODO: only update this spline */ | DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY); | ||||
| BKE_mask_update_display(mask, CFRA); | |||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) | static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| { | { | ||||
| ScrArea *sa = CTX_wm_area(C); | ScrArea *sa = CTX_wm_area(C); | ||||
| ARegion *ar = CTX_wm_region(C); | ARegion *ar = CTX_wm_region(C); | ||||
| ▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | static int add_feather_vertex_exec(bContext *C, wmOperator *op) | ||||
| point = ED_mask_point_find_nearest(C, mask, co, threshold, NULL, NULL, NULL, NULL); | point = ED_mask_point_find_nearest(C, mask, co, threshold, NULL, NULL, NULL, NULL); | ||||
| if (point) { | if (point) { | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| if (ED_mask_find_nearest_diff_point( | if (ED_mask_find_nearest_diff_point( | ||||
| C, mask, co, threshold, true, NULL, true, true, &masklay, &spline, &point, &u, NULL)) { | C, mask, co, threshold, true, NULL, true, true, &masklay, &spline, &point, &u, NULL)) { | ||||
| Scene *scene = CTX_data_scene(C); | |||||
| float w = BKE_mask_point_weight(spline, point, u); | float w = BKE_mask_point_weight(spline, point, u); | ||||
| float weight_scalar = BKE_mask_point_weight_scalar(spline, point, u); | float weight_scalar = BKE_mask_point_weight_scalar(spline, point, u); | ||||
| if (weight_scalar != 0.0f) { | if (weight_scalar != 0.0f) { | ||||
| w = w / weight_scalar; | w = w / weight_scalar; | ||||
| } | } | ||||
| BKE_mask_point_add_uw(point, u, w); | BKE_mask_point_add_uw(point, u, w); | ||||
| BKE_mask_update_display(mask, scene->r.cfra); | DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY); | ||||
| WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); | WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); | ||||
| DEG_id_tag_update(&mask->id, 0); | |||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| static int add_feather_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) | static int add_feather_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| { | { | ||||
| Show All 38 Lines | |||||
| } | } | ||||
| /******************** common primitive functions *********************/ | /******************** common primitive functions *********************/ | ||||
| static int create_primitive_from_points( | static int create_primitive_from_points( | ||||
| bContext *C, wmOperator *op, const float (*points)[2], int num_points, char handle_type) | bContext *C, wmOperator *op, const float (*points)[2], int num_points, char handle_type) | ||||
| { | { | ||||
| ScrArea *sa = CTX_wm_area(C); | ScrArea *sa = CTX_wm_area(C); | ||||
| Scene *scene = CTX_data_scene(C); | |||||
| Mask *mask; | Mask *mask; | ||||
| MaskLayer *mask_layer; | MaskLayer *mask_layer; | ||||
| MaskSpline *new_spline; | MaskSpline *new_spline; | ||||
| float scale, location[2], frame_size[2]; | float scale, location[2], frame_size[2]; | ||||
| int i, width, height; | int i, width, height; | ||||
| int size = RNA_float_get(op->ptr, "size"); | int size = RNA_float_get(op->ptr, "size"); | ||||
| ED_mask_get_size(sa, &width, &height); | ED_mask_get_size(sa, &width, &height); | ||||
| ▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | for (i = 0; i < num_points; i++) { | ||||
| } | } | ||||
| } | } | ||||
| if (added_mask) { | if (added_mask) { | ||||
| WM_event_add_notifier(C, NC_MASK | NA_ADDED, NULL); | WM_event_add_notifier(C, NC_MASK | NA_ADDED, NULL); | ||||
| } | } | ||||
| WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); | WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); | ||||
| /* TODO: only update this spline */ | DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY); | ||||
| BKE_mask_update_display(mask, CFRA); | |||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| static int primitive_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | static int primitive_add_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) | ||||
| { | { | ||||
| ScrArea *sa = CTX_wm_area(C); | ScrArea *sa = CTX_wm_area(C); | ||||
| float cursor[2]; | float cursor[2]; | ||||
| ▲ Show 20 Lines • Show All 90 Lines • Show Last 20 Lines | |||||