static int mask_select_more_less(bContext *C, bool more) { Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) { MaskSpline *spline; if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { continue; } for (spline = masklay->splines.first; spline; spline = spline->next) { const bool cyclic = (spline->flag & MASK_SPLINE_CYCLIC) != 0; bool start_sel, end_sel, prev_sel, cur_sel; int i; /* reselect point if any handle is selected to make the result more predictable */ for (i = 0; i < spline->tot_point; i++) { BKE_mask_point_select_set(spline->points + i, MASKPOINT_ISSEL_ANY(spline->points + i)); } /* select more/less does not affect empty/single point splines */ if (spline->tot_point < 2) { continue; } if (cyclic) { start_sel = !!MASKPOINT_ISSEL_KNOT(spline->points); end_sel = !!MASKPOINT_ISSEL_KNOT(&spline->points[spline->tot_point - 1]); } else { start_sel = false; end_sel = false; } for (i = 0; i < spline->tot_point; i++) { if (i == 0 && !cyclic) { continue; } prev_sel = (i > 0) ? !!MASKPOINT_ISSEL_KNOT(&spline->points[i - 1]) : end_sel; cur_sel = !!MASKPOINT_ISSEL_KNOT(&spline->points[i]); if (cur_sel != more) { if (prev_sel == more) { BKE_mask_point_select_set(&spline->points[i], more); } i++; } } for (i = spline->tot_point - 1; i >= 0; i--) { if (i == spline->tot_point - 1 && !cyclic) { continue; } prev_sel = (i < spline->tot_point - 1) ? !!MASKPOINT_ISSEL_KNOT(&spline->points[i + 1]) : start_sel; cur_sel = !!MASKPOINT_ISSEL_KNOT(&spline->points[i]); if (cur_sel != more) { if (prev_sel == more) { BKE_mask_point_select_set(&spline->points[i], more); } i--; } } } } WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); return OPERATOR_FINISHED; }
/* return non-zero if spline is selected */ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline *spline, const char draw_flag, const char draw_type, const float xscale, const float yscale) { const bool is_spline_sel = (spline->flag & SELECT) && (masklay->restrictflag & MASK_RESTRICT_SELECT) == 0; const bool is_smooth = (draw_flag & MASK_DRAWFLAG_SMOOTH) != 0; unsigned char rgb_spline[4]; MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); SpaceClip *sc = CTX_wm_space_clip(C); bool undistort = false; int i, handle_size, tot_feather_point; float (*feather_points)[2], (*fp)[2]; float min[2], max[2]; if (!spline->tot_point) return; if (sc) undistort = sc->clip && (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT); /* TODO, add this to sequence editor */ handle_size = UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE) * U.pixelsize; glPointSize(handle_size); mask_spline_color_get(masklay, spline, is_spline_sel, rgb_spline); /* feather points */ feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point); for (i = 0; i < spline->tot_point; i++) { /* watch it! this is intentionally not the deform array, only check for sel */ MaskSplinePoint *point = &spline->points[i]; int j; for (j = 0; j <= point->tot_uw; j++) { float feather_point[2]; bool sel = false; copy_v2_v2(feather_point, *fp); if (undistort) mask_point_undistort_pos(sc, feather_point, feather_point); if (j == 0) { sel = MASKPOINT_ISSEL_ANY(point); } else { sel = (point->uw[j - 1].flag & SELECT) != 0; } if (sel) { if (point == masklay->act_point) glColor3f(1.0f, 1.0f, 1.0f); else UI_ThemeColor(TH_HANDLE_VERTEX_SELECT); } else { UI_ThemeColor(TH_HANDLE_VERTEX); } glBegin(GL_POINTS); glVertex2fv(feather_point); glEnd(); fp++; } } MEM_freeN(feather_points); if (is_smooth) { glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } /* control points */ INIT_MINMAX2(min, max); for (i = 0; i < spline->tot_point; i++) { /* watch it! this is intentionally not the deform array, only check for sel */ MaskSplinePoint *point = &spline->points[i]; MaskSplinePoint *point_deform = &points_array[i]; BezTriple *bezt = &point_deform->bezt; float vert[2]; copy_v2_v2(vert, bezt->vec[1]); if (undistort) { mask_point_undistort_pos(sc, vert, vert); } /* draw handle segment */ if (BKE_mask_point_handles_mode_get(point) == MASK_HANDLE_MODE_STICK) { float handle[2]; BKE_mask_point_handle(point_deform, MASK_WHICH_HANDLE_STICK, handle); if (undistort) { mask_point_undistort_pos(sc, handle, handle); } draw_single_handle(masklay, point, MASK_WHICH_HANDLE_STICK, draw_type, handle_size, xscale, yscale, vert, handle); } else { float handle_left[2], handle_right[2]; BKE_mask_point_handle(point_deform, MASK_WHICH_HANDLE_LEFT, handle_left); BKE_mask_point_handle(point_deform, MASK_WHICH_HANDLE_RIGHT, handle_right); if (undistort) { mask_point_undistort_pos(sc, handle_left, handle_left); mask_point_undistort_pos(sc, handle_left, handle_left); } draw_single_handle(masklay, point, MASK_WHICH_HANDLE_LEFT, draw_type, handle_size, xscale, yscale, vert, handle_left); draw_single_handle(masklay, point, MASK_WHICH_HANDLE_RIGHT, draw_type, handle_size, xscale, yscale, vert, handle_right); } /* draw CV point */ if (MASKPOINT_ISSEL_KNOT(point)) { if (point == masklay->act_point) glColor3f(1.0f, 1.0f, 1.0f); else UI_ThemeColor(TH_HANDLE_VERTEX_SELECT); } else UI_ThemeColor(TH_HANDLE_VERTEX); glBegin(GL_POINTS); glVertex2fv(vert); glEnd(); minmax_v2v2_v2(min, max, vert); } if (is_spline_sel) { float x = (min[0] + max[0]) / 2.0f; float y = (min[1] + max[1]) / 2.0f; /* TODO(sergey): Remove hardcoded colors. */ if (masklay->act_spline == spline) { glColor3ub(255, 255, 255); } else { glColor3ub(255, 255, 0); } draw_circle(x, y, 6.0f, true, xscale, yscale); glColor3ub(0, 0, 0); draw_circle(x, y, 6.0f, false, xscale, yscale); } if (is_smooth) { glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); } }
/* return non-zero if spline is selected */ static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline *spline, const char UNUSED(draw_flag), const char draw_type) { const bool is_spline_sel = (spline->flag & SELECT) && (masklay->restrictflag & MASK_RESTRICT_SELECT) == 0; unsigned char rgb_spline[4]; MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); SpaceClip *sc = CTX_wm_space_clip(C); int undistort = FALSE; int i, hsize, tot_feather_point; float (*feather_points)[2], (*fp)[2]; if (!spline->tot_point) return; if (sc) undistort = sc->clip && sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT; /* TODO, add this to sequence editor */ hsize = 4; /* UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); */ glPointSize(hsize); mask_spline_color_get(masklay, spline, is_spline_sel, rgb_spline); /* feather points */ feather_points = fp = BKE_mask_spline_feather_points(spline, &tot_feather_point); for (i = 0; i < spline->tot_point; i++) { /* watch it! this is intentionally not the deform array, only check for sel */ MaskSplinePoint *point = &spline->points[i]; int j; for (j = 0; j <= point->tot_uw; j++) { float feather_point[2]; int sel = FALSE; copy_v2_v2(feather_point, *fp); if (undistort) mask_point_undistort_pos(sc, feather_point, feather_point); if (j == 0) { sel = MASKPOINT_ISSEL_ANY(point); } else { sel = point->uw[j - 1].flag & SELECT; } if (sel) { if (point == masklay->act_point) glColor3f(1.0f, 1.0f, 1.0f); else glColor3f(1.0f, 1.0f, 0.0f); } else { glColor3f(0.5f, 0.5f, 0.0f); } glBegin(GL_POINTS); glVertex2fv(feather_point); glEnd(); fp++; } } MEM_freeN(feather_points); /* control points */ for (i = 0; i < spline->tot_point; i++) { /* watch it! this is intentionally not the deform array, only check for sel */ MaskSplinePoint *point = &spline->points[i]; MaskSplinePoint *point_deform = &points_array[i]; BezTriple *bezt = &point_deform->bezt; float handle[2]; float vert[2]; const bool has_handle = BKE_mask_point_has_handle(point); copy_v2_v2(vert, bezt->vec[1]); BKE_mask_point_handle(point_deform, handle); if (undistort) { mask_point_undistort_pos(sc, vert, vert); mask_point_undistort_pos(sc, handle, handle); } /* draw handle segment */ if (has_handle) { /* this could be split into its own loop */ if (draw_type == MASK_DT_OUTLINE) { const unsigned char rgb_gray[4] = {0x60, 0x60, 0x60, 0xff}; glLineWidth(3); glColor4ubv(rgb_gray); glBegin(GL_LINES); glVertex2fv(vert); glVertex2fv(handle); glEnd(); glLineWidth(1); } glColor3ubv(rgb_spline); glBegin(GL_LINES); glVertex2fv(vert); glVertex2fv(handle); glEnd(); } /* draw CV point */ if (MASKPOINT_ISSEL_KNOT(point)) { if (point == masklay->act_point) glColor3f(1.0f, 1.0f, 1.0f); else glColor3f(1.0f, 1.0f, 0.0f); } else glColor3f(0.5f, 0.5f, 0.0f); glBegin(GL_POINTS); glVertex2fv(vert); glEnd(); /* draw handle points */ if (has_handle) { if (MASKPOINT_ISSEL_HANDLE(point)) { if (point == masklay->act_point) glColor3f(1.0f, 1.0f, 1.0f); else glColor3f(1.0f, 1.0f, 0.0f); } else { glColor3f(0.5f, 0.5f, 0.0f); } glBegin(GL_POINTS); glVertex2fv(handle); glEnd(); } } glPointSize(1.0f); }