static bool add_vertex_subdivide(const bContext *C, Mask *mask, const float co[2]) { MaskLayer *masklay; MaskSpline *spline; MaskSplinePoint *point = NULL; const float threshold = 9; float tangent[2]; float u; if (ED_mask_find_nearest_diff_point(C, mask, co, threshold, false, &masklay, &spline, &point, &u, tangent, true, true)) { MaskSplinePoint *new_point; int point_index = point - spline->points; ED_mask_select_toggle_all(mask, SEL_DESELECT); mask_spline_add_point_at_index(spline, point_index); new_point = &spline->points[point_index + 1]; setup_vertex_point(mask, spline, new_point, co, u, NULL, true); /* TODO - we could pass the spline! */ BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index + 1, true, true); masklay->act_spline = spline; masklay->act_point = new_point; WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return true; } return false; }
static int create_primitive_from_points(bContext *C, wmOperator *op, const float (*points)[2], int num_points, char handle_type) { ScrArea *sa = CTX_wm_area(C); Scene *scene = CTX_data_scene(C); Mask *mask; MaskLayer *mask_layer; MaskSpline *new_spline; float scale, location[2], frame_size[2]; int i, width, height; int size = RNA_float_get(op->ptr, "size"); ED_mask_get_size(sa, &width, &height); scale = (float)size / max_ii(width, height); /* Get location in mask space. */ frame_size[0] = width; frame_size[1] = height; RNA_float_get_array(op->ptr, "location", location); location[0] /= width; location[1] /= height; BKE_mask_coord_from_frame(location, location, frame_size); /* Make it so new primitive is centered to mouse location. */ location[0] -= 0.5f * scale; location[1] -= 0.5f * scale; mask_layer = ED_mask_layer_ensure(C); mask = CTX_data_edit_mask(C); ED_mask_select_toggle_all(mask, SEL_DESELECT); new_spline = BKE_mask_spline_add(mask_layer); new_spline->flag = MASK_SPLINE_CYCLIC | SELECT; new_spline->tot_point = num_points; new_spline->points = MEM_recallocN(new_spline->points, sizeof(MaskSplinePoint) * new_spline->tot_point); mask_layer->act_spline = new_spline; mask_layer->act_point = NULL; for (i = 0; i < num_points; i++) { MaskSplinePoint *new_point = &new_spline->points[i]; copy_v2_v2(new_point->bezt.vec[1], points[i]); mul_v2_fl(new_point->bezt.vec[1], scale); add_v2_v2(new_point->bezt.vec[1], location); new_point->bezt.h1 = handle_type; new_point->bezt.h2 = handle_type; BKE_mask_point_select_set(new_point, true); } WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); /* TODO: only update this spline */ BKE_mask_update_display(mask, CFRA); return OPERATOR_FINISHED; }
static bool add_vertex_new(const bContext *C, Mask *mask, MaskLayer *masklay, const float co[2]) { Scene *scene = CTX_data_scene(C); const float ctime = CFRA; MaskSpline *spline; MaskSplinePoint *new_point = NULL, *ref_point = NULL; if (!masklay) { /* if there's no masklay currently operationg on, create new one */ masklay = BKE_mask_layer_new(mask, ""); mask->masklay_act = mask->masklay_tot - 1; } ED_mask_select_toggle_all(mask, SEL_DESELECT); spline = BKE_mask_spline_add(masklay); masklay->act_spline = spline; new_point = spline->points; masklay->act_point = new_point; setup_vertex_point(mask, spline, new_point, co, 0.5f, ctime, ref_point, false); { int point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index, true, true); } WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return true; }
static int add_vertex_new(const bContext *C, Mask *mask, MaskLayer *masklay, const float co[2]) { MaskSpline *spline; MaskSplinePoint *point; MaskSplinePoint *new_point = NULL, *ref_point = NULL; float view_zoom; if (!masklay) { /* if there's no masklay currently operationg on, create new one */ masklay = BKE_mask_layer_new(mask, ""); mask->masklay_act = mask->masklay_tot - 1; spline = NULL; point = NULL; } else { finSelectedSplinePoint(masklay, &spline, &point, TRUE); } ED_mask_select_toggle_all(mask, SEL_DESELECT); if (!spline) { /* no selected splines in active masklay, create new spline */ spline = BKE_mask_spline_add(masklay); } masklay->act_spline = spline; new_point = spline->points; masklay->act_point = new_point; { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); float zoom_x, zoom_y; /* calc view zoom in a simplistic way */ ED_mask_zoom(sa, ar, &zoom_x, &zoom_y); view_zoom = zoom_x + zoom_y / 2.0f; view_zoom = 1.0f / view_zoom; /* arbitrary but gives good results */ view_zoom /= 500.0f; } setup_vertex_point(mask, spline, new_point, co, NULL, 0.5f, ref_point, FALSE, view_zoom); { int point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index, TRUE, TRUE); } WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return TRUE; }
static int select_all_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); int action = RNA_enum_get(op->ptr, "action"); ED_mask_select_toggle_all(mask, action); ED_mask_select_flush_all(mask); WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); return OPERATOR_FINISHED; }
static int slide_point_invoke(bContext *C, wmOperator *op, const wmEvent *event) { SlidePointData *slidedata = slide_point_customdata(C, op, event); if (slidedata) { Mask *mask = CTX_data_edit_mask(C); op->customdata = slidedata; WM_event_add_modal_handler(C, op); #if 0 if (slidedata->uw) { if ((slidedata->uw->flag & SELECT) == 0) { ED_mask_select_toggle_all(mask, SEL_DESELECT); slidedata->uw->flag |= SELECT; ED_mask_select_flush_all(mask); } } else if (!MASKPOINT_ISSEL_ANY(slidedata->point)) { ED_mask_select_toggle_all(mask, SEL_DESELECT); BKE_mask_point_select_set(slidedata->point, TRUE); ED_mask_select_flush_all(mask); } #endif slidedata->masklay->act_spline = slidedata->spline; slidedata->masklay->act_point = slidedata->point; WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); return OPERATOR_RUNNING_MODAL; } return OPERATOR_PASS_THROUGH; }
static bool add_vertex_extrude(const bContext *C, Mask *mask, MaskLayer *masklay, const float co[2]) { MaskSpline *spline; MaskSplinePoint *point; MaskSplinePoint *new_point = NULL, *ref_point = NULL; /* check on which side we want to add the point */ int point_index; float tangent_point[2]; float tangent_co[2]; bool do_cyclic_correct = false; bool do_prev; /* use prev point rather then next?? */ if (!masklay) { return false; } else { finSelectedSplinePoint(masklay, &spline, &point, true); } ED_mask_select_toggle_all(mask, SEL_DESELECT); point_index = (point - spline->points); MASKPOINT_DESEL_ALL(point); if ((spline->flag & MASK_SPLINE_CYCLIC) || (point_index > 0 && point_index != spline->tot_point - 1)) { BKE_mask_calc_tangent_polyline(spline, point, tangent_point); sub_v2_v2v2(tangent_co, co, point->bezt.vec[1]); if (dot_v2v2(tangent_point, tangent_co) < 0.0f) { do_prev = true; } else { do_prev = false; } } else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == 0)) { do_prev = true; } else if (((spline->flag & MASK_SPLINE_CYCLIC) == 0) && (point_index == spline->tot_point - 1)) { do_prev = false; } else { do_prev = false; /* quiet warning */ /* should never get here */ BLI_assert(0); } /* use the point before the active one */ if (do_prev) { point_index--; if (point_index < 0) { point_index += spline->tot_point; /* wrap index */ if ((spline->flag & MASK_SPLINE_CYCLIC) == 0) { do_cyclic_correct = true; point_index = 0; } } } // print_v2("", tangent_point); // printf("%d\n", point_index); mask_spline_add_point_at_index(spline, point_index); if (do_cyclic_correct) { ref_point = &spline->points[point_index + 1]; new_point = &spline->points[point_index]; *ref_point = *new_point; memset(new_point, 0, sizeof(*new_point)); } else { ref_point = &spline->points[point_index]; new_point = &spline->points[point_index + 1]; } masklay->act_point = new_point; setup_vertex_point(mask, spline, new_point, co, 0.5f, ref_point, false); if (masklay->splines_shapes.first) { point_index = (((int)(new_point - spline->points) + 0) % spline->tot_point); BKE_mask_layer_shape_changed_add(masklay, BKE_mask_layer_shape_spline_to_index(masklay, spline) + point_index, true, true); } WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask); return true; }
static int select_exec(bContext *C, wmOperator *op) { Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; MaskSpline *spline; MaskSplinePoint *point = NULL; float co[2]; bool extend = RNA_boolean_get(op->ptr, "extend"); bool deselect = RNA_boolean_get(op->ptr, "deselect"); bool toggle = RNA_boolean_get(op->ptr, "toggle"); eMaskWhichHandle which_handle; const float threshold = 19; RNA_float_get_array(op->ptr, "location", co); point = ED_mask_point_find_nearest(C, mask, co, threshold, &masklay, &spline, &which_handle, NULL); if (extend == false && deselect == false && toggle == false) ED_mask_select_toggle_all(mask, SEL_DESELECT); if (point) { if (which_handle != MASK_WHICH_HANDLE_NONE) { if (extend) { masklay->act_spline = spline; masklay->act_point = point; BKE_mask_point_select_set_handle(point, which_handle, true); } else if (deselect) { BKE_mask_point_select_set_handle(point, which_handle, false); } else { masklay->act_spline = spline; masklay->act_point = point; if (!MASKPOINT_ISSEL_HANDLE(point, which_handle)) { BKE_mask_point_select_set_handle(point, which_handle, true); } else if (toggle) { BKE_mask_point_select_set_handle(point, which_handle, false); } } } else { if (extend) { masklay->act_spline = spline; masklay->act_point = point; BKE_mask_point_select_set(point, true); } else if (deselect) { BKE_mask_point_select_set(point, false); } else { masklay->act_spline = spline; masklay->act_point = point; if (!MASKPOINT_ISSEL_ANY(point)) { BKE_mask_point_select_set(point, true); } else if (toggle) { BKE_mask_point_select_set(point, false); } } } masklay->act_spline = spline; masklay->act_point = point; ED_mask_select_flush_all(mask); WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); return OPERATOR_FINISHED; } else { MaskSplinePointUW *uw; if (ED_mask_feather_find_nearest(C, mask, co, threshold, &masklay, &spline, &point, &uw, NULL)) { if (extend) { masklay->act_spline = spline; masklay->act_point = point; if (uw) uw->flag |= SELECT; } else if (deselect) { if (uw) uw->flag &= ~SELECT; } else { masklay->act_spline = spline; masklay->act_point = point; if (uw) { if (!(uw->flag & SELECT)) { uw->flag |= SELECT; } else if (toggle) { uw->flag &= ~SELECT; } } } ED_mask_select_flush_all(mask); WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); return OPERATOR_FINISHED; } } return OPERATOR_PASS_THROUGH; }