static int add_feather_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); float co[2]; ED_mask_mouse_pos(sa, ar, event->mval, co); RNA_float_set_array(op->ptr, "location", co); return add_feather_vertex_exec(C, op); }
static int mask_select_linked_pick_invoke(bContext *C, wmOperator *op, wmEvent *event) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; MaskSpline *spline; MaskSplinePoint *point = NULL; float co[2]; int do_select = !RNA_boolean_get(op->ptr, "deselect"); int is_handle = 0; const float threshold = 19; int change = FALSE; ED_mask_mouse_pos(sa, ar, event->mval, co); point = ED_mask_point_find_nearest(C, mask, co, threshold, &masklay, &spline, &is_handle, NULL); if (point) { ED_mask_spline_select_set(spline, do_select); masklay->act_spline = spline; masklay->act_point = point; change = TRUE; } if (change) { ED_mask_select_flush_all(mask); WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); return OPERATOR_FINISHED; } return OPERATOR_CANCELLED; }
static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event) { SlidePointData *data = (SlidePointData *)op->customdata; BezTriple *bezt = &data->point->bezt; float co[2], dco[2]; switch (event->type) { case LEFTALTKEY: case RIGHTALTKEY: case LEFTSHIFTKEY: case RIGHTSHIFTKEY: if (ELEM(event->type, LEFTALTKEY, RIGHTALTKEY)) { if (data->action == SLIDE_ACTION_FEATHER) data->overall_feather = (event->val == KM_PRESS); else data->curvature_only = (event->val == KM_PRESS); } if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) data->accurate = (event->val == KM_PRESS); /* fall-through */ /* update CV position */ case MOUSEMOVE: { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); ED_mask_mouse_pos(sa, ar, event->mval, co); sub_v2_v2v2(dco, co, data->co); if (data->action == SLIDE_ACTION_HANDLE) { float delta[2], offco[2]; sub_v2_v2v2(delta, data->handle, data->co); sub_v2_v2v2(offco, co, data->co); if (data->accurate) mul_v2_fl(offco, 0.2f); add_v2_v2(offco, data->co); add_v2_v2(offco, delta); BKE_mask_point_set_handle(data->point, offco, data->curvature_only, data->handle, data->vec); } else if (data->action == SLIDE_ACTION_POINT) { float delta[2]; copy_v2_v2(delta, dco); if (data->accurate) mul_v2_fl(delta, 0.2f); add_v2_v2v2(bezt->vec[0], data->vec[0], delta); add_v2_v2v2(bezt->vec[1], data->vec[1], delta); add_v2_v2v2(bezt->vec[2], data->vec[2], delta); } else if (data->action == SLIDE_ACTION_FEATHER) { float vec[2], no[2], p[2], c[2], w, offco[2]; float *weight = NULL; float weight_scalar = 1.0f; int overall_feather = data->overall_feather || data->initial_feather; add_v2_v2v2(offco, data->feather, dco); if (data->uw) { /* project on both sides and find the closest one, * prevents flickering when projecting onto both sides can happen */ const float u_pos = BKE_mask_spline_project_co(data->spline, data->point, data->uw->u, offco, MASK_PROJ_NEG); const float u_neg = BKE_mask_spline_project_co(data->spline, data->point, data->uw->u, offco, MASK_PROJ_POS); float dist_pos = FLT_MAX; float dist_neg = FLT_MAX; float co_pos[2]; float co_neg[2]; float u; if (u_pos > 0.0f && u_pos < 1.0f) { BKE_mask_point_segment_co(data->spline, data->point, u_pos, co_pos); dist_pos = len_squared_v2v2(offco, co_pos); } if (u_neg > 0.0f && u_neg < 1.0f) { BKE_mask_point_segment_co(data->spline, data->point, u_neg, co_neg); dist_neg = len_squared_v2v2(offco, co_neg); } u = dist_pos < dist_neg ? u_pos : u_neg; if (u > 0.0f && u < 1.0f) { data->uw->u = u; data->uw = BKE_mask_point_sort_uw(data->point, data->uw); weight = &data->uw->w; weight_scalar = BKE_mask_point_weight_scalar(data->spline, data->point, u); if (weight_scalar != 0.0f) { weight_scalar = 1.0f / weight_scalar; } BKE_mask_point_normal(data->spline, data->point, data->uw->u, no); BKE_mask_point_segment_co(data->spline, data->point, data->uw->u, p); } } else { weight = &bezt->weight; /* weight_scalar = 1.0f; keep as is */ copy_v2_v2(no, data->no); copy_v2_v2(p, bezt->vec[1]); } if (weight) { sub_v2_v2v2(c, offco, p); project_v2_v2v2(vec, c, no); w = len_v2(vec); if (overall_feather) { float delta; if (dot_v2v2(no, vec) <= 0.0f) w = -w; delta = w - data->weight * data->weight_scalar; if (data->orig_spline == NULL) { /* restore weight for currently sliding point, so orig_spline would be created * with original weights used */ *weight = data->weight; data->orig_spline = BKE_mask_spline_copy(data->spline); } slide_point_delta_all_feather(data, delta); } else { if (dot_v2v2(no, vec) <= 0.0f) w = 0.0f; if (data->orig_spline) { /* restore possible overall feather changes */ slide_point_restore_spline(data); BKE_mask_spline_free(data->orig_spline); data->orig_spline = NULL; } if (weight_scalar != 0.0f) { *weight = w * weight_scalar; } } } } WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask); DAG_id_tag_update(&data->mask->id, 0); break; } case LEFTMOUSE: if (event->val == KM_RELEASE) { Scene *scene = CTX_data_scene(C); /* dont key sliding feather uw's */ if ((data->action == SLIDE_ACTION_FEATHER && data->uw) == FALSE) { if (IS_AUTOKEY_ON(scene)) { ED_mask_layer_shape_auto_key(data->masklay, CFRA); } } WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask); DAG_id_tag_update(&data->mask->id, 0); free_slide_point_data(op->customdata); /* keep this last! */ return OPERATOR_FINISHED; } break; case ESCKEY: cancel_slide_point(op->customdata); WM_event_add_notifier(C, NC_MASK | NA_EDITED, data->mask); DAG_id_tag_update(&data->mask->id, 0); free_slide_point_data(op->customdata); /* keep this last! */ return OPERATOR_CANCELLED; } return OPERATOR_RUNNING_MODAL; }
static void *slide_point_customdata(bContext *C, wmOperator *op, const wmEvent *event) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); Mask *mask = CTX_data_edit_mask(C); SlidePointData *customdata = NULL; MaskLayer *masklay, *cv_masklay, *feather_masklay; MaskSpline *spline, *cv_spline, *feather_spline; MaskSplinePoint *point, *cv_point, *feather_point; MaskSplinePointUW *uw = NULL; int width, height, action = SLIDE_ACTION_NONE; bool is_handle = false; const bool slide_feather = RNA_boolean_get(op->ptr, "slide_feather"); float co[2], cv_score, feather_score; const float threshold = 19; ED_mask_mouse_pos(sa, ar, event->mval, co); ED_mask_get_size(sa, &width, &height); cv_point = ED_mask_point_find_nearest(C, mask, co, threshold, &cv_masklay, &cv_spline, &is_handle, &cv_score); if (ED_mask_feather_find_nearest(C, mask, co, threshold, &feather_masklay, &feather_spline, &feather_point, &uw, &feather_score)) { if (slide_feather || !cv_point || feather_score < cv_score) { action = SLIDE_ACTION_FEATHER; masklay = feather_masklay; spline = feather_spline; point = feather_point; } } if (cv_point && action == SLIDE_ACTION_NONE) { if (is_handle) action = SLIDE_ACTION_HANDLE; else action = SLIDE_ACTION_POINT; masklay = cv_masklay; spline = cv_spline; point = cv_point; } if (action != SLIDE_ACTION_NONE) { customdata = MEM_callocN(sizeof(SlidePointData), "mask slide point data"); customdata->mask = mask; customdata->masklay = masklay; customdata->spline = spline; customdata->point = point; customdata->width = width; customdata->height = height; customdata->action = action; customdata->uw = uw; if (uw) { float co_uw[2]; float weight_scalar = BKE_mask_point_weight_scalar(spline, point, uw->u); customdata->weight = uw->w; customdata->weight_scalar = weight_scalar; BKE_mask_point_segment_co(spline, point, uw->u, co_uw); BKE_mask_point_normal(spline, point, uw->u, customdata->no); madd_v2_v2v2fl(customdata->feather, co_uw, customdata->no, uw->w * weight_scalar); } else { BezTriple *bezt = &point->bezt; customdata->weight = bezt->weight; customdata->weight_scalar = 1.0f; BKE_mask_point_normal(spline, point, 0.0f, customdata->no); madd_v2_v2v2fl(customdata->feather, bezt->vec[1], customdata->no, bezt->weight); } if (customdata->action == SLIDE_ACTION_FEATHER) customdata->initial_feather = slide_point_check_initial_feather(spline); copy_m3_m3(customdata->vec, point->bezt.vec); if (BKE_mask_point_has_handle(point)) BKE_mask_point_handle(point, customdata->handle); ED_mask_mouse_pos(sa, ar, event->mval, customdata->co); } return customdata; }