From c8d29b19968cafe91937ea3c26afef819372c599 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 12 Jul 2012 09:03:45 +0000 Subject: feather points now align with mask outline when called with same resolution. --- source/blender/blenkernel/intern/mask.c | 86 +++++++++++++++++++++++++-------- 1 file changed, 66 insertions(+), 20 deletions(-) diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c index ea152e4c188..2326a8fa59c 100644 --- a/source/blender/blenkernel/intern/mask.c +++ b/source/blender/blenkernel/intern/mask.c @@ -314,6 +314,23 @@ static int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int return resol; } +static int mask_spline_points_calc_tot(const MaskSpline *spline, const int resol) +{ + int len; + + /* count */ + len = (spline->tot_point - 1) * resol; + + if (spline->flag & MASK_SPLINE_CYCLIC) { + len += resol; + } + else { + len++; + } + + return len; +} + float (*BKE_mask_spline_differentiate_with_resolution_ex(MaskSpline *spline, const int resol, int *tot_diff_point))[2] { @@ -321,7 +338,8 @@ float (*BKE_mask_spline_differentiate_with_resolution_ex(MaskSpline *spline, con MaskSplinePoint *point, *prev; float (*diff_points)[2], (*fp)[2]; - int a, len; + const int tot = mask_spline_points_calc_tot(spline, resol); + int a; if (spline->tot_point <= 1) { /* nothing to differentiate */ @@ -329,17 +347,9 @@ float (*BKE_mask_spline_differentiate_with_resolution_ex(MaskSpline *spline, con return NULL; } - /* count */ - len = (spline->tot_point - 1) * resol; - - if (spline->flag & MASK_SPLINE_CYCLIC) - len += resol; - else - len++; - /* len+1 because of 'forward_diff_bezier' function */ - *tot_diff_point = len; - diff_points = fp = MEM_mallocN((len + 1) * sizeof(*diff_points), "mask spline vets"); + *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) @@ -391,19 +401,41 @@ float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point))[ return BKE_mask_spline_differentiate_with_resolution(spline, 0, 0, tot_diff_point); } +/** + * values align with #BKE_mask_spline_differentiate_with_resolution_ex + * when \a resol arguments match. + */ float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpline *spline, const int resol, int *tot_feather_point))[2] { MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); - + MaskSplinePoint *point, *prev; float (*feather)[2], (*fp)[2]; - int i, j, tot; - tot = resol * spline->tot_point; - feather = fp = MEM_mallocN(tot * sizeof(*feather), "mask spline feather diff points"); + const int tot = mask_spline_points_calc_tot(spline, resol); + int a; - for (i = 0; i < spline->tot_point; i++) { - MaskSplinePoint *point = &points_array[i]; + /* 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++; + + prev = points_array; + point = prev + 1; + + while (a--) { + /* BezTriple *prevbezt; */ /* UNUSED */ + /* BezTriple *bezt; */ /* UNUSED */ + int j; + + if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC)) + point = points_array; + + + /* prevbezt = &prev->bezt; */ + /* bezt = &point->bezt; */ for (j = 0; j < resol; j++, fp++) { float u = (float) j / resol, weight; @@ -411,12 +443,26 @@ float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpl /* TODO - these calls all calculate similar things * could be unified for some speed */ - 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); + BKE_mask_point_segment_co(spline, prev, u, co); + BKE_mask_point_normal(spline, prev, u, n); + weight = BKE_mask_point_weight(spline, 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, prev, u, co); + BKE_mask_point_normal(spline, prev, u, n); + weight = BKE_mask_point_weight(spline, prev, u); + + madd_v2_v2v2fl(*fp, co, n, weight); + } + + prev = point; + point++; } *tot_feather_point = tot; -- cgit v1.2.3