static void draw_spline_parents(MaskLayer *UNUSED(masklay), MaskSpline *spline) { int i; MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); if (!spline->tot_point) return; GPU_basic_shader_bind_enable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE); GPU_basic_shader_line_stipple(1, 0xAAAA); glColor3ub(0, 0, 0); glBegin(GL_LINES); for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &points_array[i]; BezTriple *bezt = &point->bezt; if (point->parent.id) { glVertex2f(bezt->vec[1][0], bezt->vec[1][1]); glVertex2f(bezt->vec[1][0] - point->parent.offset[0], bezt->vec[1][1] - point->parent.offset[1]); } } glEnd(); GPU_basic_shader_bind_disable(GPU_SHADER_LINE | GPU_SHADER_STIPPLE); }
static bool do_lasso_select_mask(bContext *C, const int mcords[][2], short moves, short select) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; int i; rcti rect; bool changed = false; /* get rectangle from operator */ BLI_lasso_boundbox(&rect, mcords, moves); /* do actual selection */ 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) { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; MaskSplinePoint *point_deform = &points_array[i]; /* TODO: handles? */ /* TODO: uw? */ float screen_co[2]; /* point in screen coords */ ED_mask_point_pos__reverse(sa, ar, point_deform->bezt.vec[1][0], point_deform->bezt.vec[1][1], &screen_co[0], &screen_co[1]); if (BLI_rcti_isect_pt(&rect, screen_co[0], screen_co[1]) && BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], INT_MAX)) { BKE_mask_point_select_set(point, select); BKE_mask_point_select_set_handle(point, MASK_WHICH_HANDLE_BOTH, select); } changed = true; } } } if (changed) { ED_mask_select_flush_all(mask); WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); } return changed; }
float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline, unsigned int *tot_diff_point, const unsigned int resol ))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); MaskSplinePoint *point_curr, *point_prev; float (*diff_points)[2], (*fp)[2]; const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol); int a; if (spline->tot_point <= 1) { /* nothing to differentiate */ *tot_diff_point = 0; return NULL; } /* len+1 because of 'forward_diff_bezier' function */ *tot_diff_point = tot; diff_points = fp = MEM_mallocN((tot + 1) * sizeof(*diff_points), "mask spline vets"); a = spline->tot_point - 1; if (spline->flag & MASK_SPLINE_CYCLIC) a++; point_prev = points_array; point_curr = point_prev + 1; while (a--) { BezTriple *bezt_prev; BezTriple *bezt_curr; int j; if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC)) point_curr = points_array; bezt_prev = &point_prev->bezt; bezt_curr = &point_curr->bezt; for (j = 0; j < 2; j++) { BKE_curve_forward_diff_bezier(bezt_prev->vec[1][j], bezt_prev->vec[2][j], bezt_curr->vec[0][j], bezt_curr->vec[1][j], &(*fp)[j], resol, 2 * sizeof(float)); } fp += resol; if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) { copy_v2_v2(*fp, bezt_curr->vec[1]); } point_prev = point_curr; point_curr++; } return diff_points; }
float (*BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); int i, tot = 0; float (*feather)[2], (*fp)[2]; /* count */ for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &points_array[i]; tot += point->tot_uw + 1; } /* create data */ feather = fp = MEM_mallocN(tot * sizeof(*feather), "mask spline feather points"); for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &points_array[i]; BezTriple *bezt = &point->bezt; float weight, n[2]; int j; BKE_mask_point_normal(spline, point, 0.0f, n); weight = BKE_mask_point_weight(spline, point, 0.0f); madd_v2_v2v2fl(*fp, bezt->vec[1], n, weight); fp++; for (j = 0; j < point->tot_uw; j++) { float u = point->uw[j].u; float co[2]; BKE_mask_point_segment_co(spline, point, u, co); BKE_mask_point_normal(spline, point, u, n); weight = BKE_mask_point_weight(spline, point, u); madd_v2_v2v2fl(*fp, co, n, weight); fp++; } } *tot_feather_point = tot; return feather; }
MaskSplinePoint *ED_mask_point_find_nearest(const bContext *C, Mask *mask, const float normal_co[2], const float threshold, MaskLayer **masklay_r, MaskSpline **spline_r, bool *is_handle_r, float *score) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); MaskLayer *masklay; MaskLayer *point_masklay = NULL; MaskSpline *point_spline = NULL; MaskSplinePoint *point = NULL; float co[2]; const float threshold_sq = threshold * threshold; float len_sq = FLT_MAX, scalex, scaley; int is_handle = FALSE, width, height; ED_mask_get_size(sa, &width, &height); ED_mask_pixelspace_factor(sa, ar, &scalex, &scaley); co[0] = normal_co[0] * scalex; co[1] = normal_co[1] * scaley; 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) { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); int i; for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *cur_point = &spline->points[i]; MaskSplinePoint *cur_point_deform = &points_array[i]; float cur_len_sq, vec[2], handle[2]; vec[0] = cur_point_deform->bezt.vec[1][0] * scalex; vec[1] = cur_point_deform->bezt.vec[1][1] * scaley; if (BKE_mask_point_has_handle(cur_point)) { BKE_mask_point_handle(cur_point_deform, handle); handle[0] *= scalex; handle[1] *= scaley; cur_len_sq = len_squared_v2v2(co, handle); if (cur_len_sq < len_sq) { point_masklay = masklay; point_spline = spline; point = cur_point; len_sq = cur_len_sq; is_handle = TRUE; } } cur_len_sq = len_squared_v2v2(co, vec); if (cur_len_sq < len_sq) { point_spline = spline; point_masklay = masklay; point = cur_point; len_sq = cur_len_sq; is_handle = FALSE; } } } } if (len_sq < threshold_sq) { if (masklay_r) *masklay_r = point_masklay; if (spline_r) *spline_r = point_spline; if (is_handle_r) *is_handle_r = is_handle; if (score) *score = sqrtf(len_sq); return point; } if (masklay_r) *masklay_r = NULL; if (spline_r) *spline_r = NULL; if (is_handle_r) *is_handle_r = FALSE; return NULL; }
/* 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); } }
static int circle_select_exec(bContext *C, wmOperator *op) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; int i; float zoomx, zoomy, offset[2], ellipse[2]; int width, height; bool changed = false; /* get operator properties */ const int x = RNA_int_get(op->ptr, "x"); const int y = RNA_int_get(op->ptr, "y"); const int radius = RNA_int_get(op->ptr, "radius"); const bool select = !RNA_boolean_get(op->ptr, "deselect"); /* compute ellipse and position in unified coordinates */ ED_mask_get_size(sa, &width, &height); ED_mask_zoom(sa, ar, &zoomx, &zoomy); width = height = max_ii(width, height); ellipse[0] = width * zoomx / radius; ellipse[1] = height * zoomy / radius; ED_mask_point_pos(sa, ar, x, y, &offset[0], &offset[1]); /* do actual selection */ 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) { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; MaskSplinePoint *point_deform = &points_array[i]; if (mask_spline_point_inside_ellipse(&point_deform->bezt, offset, ellipse)) { BKE_mask_point_select_set(point, select); BKE_mask_point_select_set_handle(point, MASK_WHICH_HANDLE_BOTH, select); changed = true; } } } } if (changed) { ED_mask_select_flush_all(mask); WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); return OPERATOR_FINISHED; } return OPERATOR_CANCELLED; }
static int border_select_exec(bContext *C, wmOperator *op) { ScrArea *sa = CTX_wm_area(C); ARegion *ar = CTX_wm_region(C); Mask *mask = CTX_data_edit_mask(C); MaskLayer *masklay; int i; rcti rect; rctf rectf; bool changed = false; const bool select = !RNA_boolean_get(op->ptr, "deselect"); const bool extend = RNA_boolean_get(op->ptr, "extend"); /* get rectangle from operator */ WM_operator_properties_border_to_rcti(op, &rect); ED_mask_point_pos(sa, ar, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin); ED_mask_point_pos(sa, ar, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax); /* do actual selection */ 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) { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); for (i = 0; i < spline->tot_point; i++) { MaskSplinePoint *point = &spline->points[i]; MaskSplinePoint *point_deform = &points_array[i]; /* TODO: handles? */ /* TODO: uw? */ if (BLI_rctf_isect_pt_v(&rectf, point_deform->bezt.vec[1])) { BKE_mask_point_select_set(point, select); BKE_mask_point_select_set_handle(point, MASK_WHICH_HANDLE_BOTH, select); } else if (!extend) { BKE_mask_point_select_set(point, false); BKE_mask_point_select_set_handle(point, MASK_WHICH_HANDLE_BOTH, false); } changed = true; } } } if (changed) { ED_mask_select_flush_all(mask); WM_event_add_notifier(C, NC_MASK | ND_SELECT, mask); return OPERATOR_FINISHED; } return OPERATOR_CANCELLED; }
/** only called from #BKE_mask_spline_feather_differentiated_points_with_resolution() ! */ static float (*mask_spline_feather_differentiated_points_with_resolution__double( MaskSpline *spline, unsigned int *tot_feather_point, const unsigned int resol, const bool do_feather_isect))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); MaskSplinePoint *point_curr, *point_prev; float (*feather)[2], (*fp)[2]; const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol); int a; if (spline->tot_point <= 1) { /* nothing to differentiate */ *tot_feather_point = 0; return NULL; } /* len+1 because of 'forward_diff_bezier' function */ *tot_feather_point = tot; feather = fp = MEM_mallocN((tot + 1) * sizeof(*feather), "mask spline vets"); a = spline->tot_point - 1; if (spline->flag & MASK_SPLINE_CYCLIC) a++; point_prev = points_array; point_curr = point_prev + 1; while (a--) { BezTriple local_prevbezt; BezTriple local_bezt; float point_prev_n[2], point_curr_n[2], tvec[2]; float weight_prev, weight_curr; float len_base, len_feather, len_scalar; BezTriple *bezt_prev; BezTriple *bezt_curr; int j; if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC)) point_curr = points_array; bezt_prev = &point_prev->bezt; bezt_curr = &point_curr->bezt; /* modified copy for feather */ local_prevbezt = *bezt_prev; local_bezt = *bezt_curr; bezt_prev = &local_prevbezt; bezt_curr = &local_bezt; /* calc the normals */ sub_v2_v2v2(tvec, bezt_prev->vec[1], bezt_prev->vec[0]); normalize_v2(tvec); point_prev_n[0] = -tvec[1]; point_prev_n[1] = tvec[0]; sub_v2_v2v2(tvec, bezt_curr->vec[1], bezt_curr->vec[0]); normalize_v2(tvec); point_curr_n[0] = -tvec[1]; point_curr_n[1] = tvec[0]; weight_prev = bezt_prev->weight; weight_curr = bezt_curr->weight; mul_v2_fl(point_prev_n, weight_prev); mul_v2_fl(point_curr_n, weight_curr); /* before we transform verts */ len_base = len_v2v2(bezt_prev->vec[1], bezt_curr->vec[1]); // add_v2_v2(bezt_prev->vec[0], point_prev_n); // not needed add_v2_v2(bezt_prev->vec[1], point_prev_n); add_v2_v2(bezt_prev->vec[2], point_prev_n); add_v2_v2(bezt_curr->vec[0], point_curr_n); add_v2_v2(bezt_curr->vec[1], point_curr_n); // add_v2_v2(bezt_curr->vec[2], point_curr_n); // not needed len_feather = len_v2v2(bezt_prev->vec[1], bezt_curr->vec[1]); /* scale by chane in length */ len_scalar = len_feather / len_base; dist_ensure_v2_v2fl(bezt_prev->vec[2], bezt_prev->vec[1], len_scalar * len_v2v2(bezt_prev->vec[2], bezt_prev->vec[1])); dist_ensure_v2_v2fl(bezt_curr->vec[0], bezt_curr->vec[1], len_scalar * len_v2v2(bezt_curr->vec[0], bezt_curr->vec[1])); for (j = 0; j < 2; j++) { BKE_curve_forward_diff_bezier(bezt_prev->vec[1][j], bezt_prev->vec[2][j], bezt_curr->vec[0][j], bezt_curr->vec[1][j], &(*fp)[j], resol, 2 * sizeof(float)); } /* scale by the uw's */ if (point_prev->tot_uw) { for (j = 0; j < resol; j++, fp++) { float u = (float) j / resol; float weight_uw, weight_scalar; float co[2]; /* TODO - these calls all calculate similar things * could be unified for some speed */ BKE_mask_point_segment_co(spline, point_prev, u, co); weight_uw = BKE_mask_point_weight(spline, point_prev, u); weight_scalar = BKE_mask_point_weight_scalar(spline, point_prev, u); dist_ensure_v2_v2fl(*fp, co, len_v2v2(*fp, co) * (weight_uw / weight_scalar)); } } else { fp += resol; } if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) { copy_v2_v2(*fp, bezt_curr->vec[1]); } point_prev = point_curr; point_curr++; } if ((spline->flag & MASK_SPLINE_NOINTERSECT) && do_feather_isect) { BKE_mask_spline_feather_collapse_inner_loops(spline, feather, tot); } return feather; }
/** only called from #BKE_mask_spline_feather_differentiated_points_with_resolution() ! */ static float (*mask_spline_feather_differentiated_points_with_resolution__even( MaskSpline *spline, unsigned int *tot_feather_point, const unsigned int resol, const bool do_feather_isect))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); MaskSplinePoint *point_curr, *point_prev; float (*feather)[2], (*fp)[2]; const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol); int a; /* tot+1 because of 'forward_diff_bezier' function */ feather = fp = MEM_mallocN((tot + 1) * sizeof(*feather), "mask spline feather diff points"); a = spline->tot_point - 1; if (spline->flag & MASK_SPLINE_CYCLIC) a++; point_prev = points_array; point_curr = point_prev + 1; while (a--) { /* BezTriple *bezt_prev; */ /* UNUSED */ /* BezTriple *bezt_curr; */ /* UNUSED */ int j; if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC)) point_curr = points_array; /* bezt_prev = &point_prev->bezt; */ /* bezt_curr = &point_curr->bezt; */ for (j = 0; j < resol; j++, fp++) { float u = (float) j / resol, weight; float co[2], n[2]; /* TODO - these calls all calculate similar things * could be unified for some speed */ BKE_mask_point_segment_co(spline, point_prev, u, co); BKE_mask_point_normal(spline, point_prev, u, n); weight = BKE_mask_point_weight(spline, point_prev, u); madd_v2_v2v2fl(*fp, co, n, weight); } if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) { float u = 1.0f, weight; float co[2], n[2]; BKE_mask_point_segment_co(spline, point_prev, u, co); BKE_mask_point_normal(spline, point_prev, u, n); weight = BKE_mask_point_weight(spline, point_prev, u); madd_v2_v2v2fl(*fp, co, n, weight); } point_prev = point_curr; point_curr++; } *tot_feather_point = tot; if ((spline->flag & MASK_SPLINE_NOINTERSECT) && do_feather_isect) { BKE_mask_spline_feather_collapse_inner_loops(spline, feather, tot); } return feather; }
/* 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); }