feather points now align with mask outline when called with same resolution.
authorCampbell Barton <ideasman42@gmail.com>
Thu, 12 Jul 2012 09:03:45 +0000 (09:03 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 12 Jul 2012 09:03:45 +0000 (09:03 +0000)
source/blender/blenkernel/intern/mask.c

index ea152e4c188cff6c0098dfec60abd386a8850f55..2326a8fa59cfc2396b8af5cdc0174bb875d7ce78 100644 (file)
@@ -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;