Merge branch 'blender2.7'
[blender.git] / source / blender / blenkernel / intern / mask_evaluate.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2012 Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup bke
22  *
23  * Functions for evaluating the mask beziers into points for the outline and feather.
24  */
25
26 #include <stddef.h>
27 #include <string.h>
28
29 #include "MEM_guardedalloc.h"
30
31 #include "BLI_utildefines.h"
32 #include "BLI_math.h"
33
34 #include "DNA_mask_types.h"
35 #include "DNA_object_types.h"
36
37 #include "BKE_curve.h"
38 #include "BKE_mask.h"
39
40 #include "DEG_depsgraph.h"
41 #include "DEG_depsgraph_query.h"
42
43 unsigned int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height)
44 {
45         float max_segment = 0.01f;
46         unsigned int i, resol = 1;
47
48         if (width != 0 && height != 0) {
49                 max_segment = 1.0f / (float)max_ii(width, height);
50         }
51
52         for (i = 0; i < spline->tot_point; i++) {
53                 MaskSplinePoint *point = &spline->points[i];
54                 BezTriple *bezt_curr, *bezt_next;
55                 float a, b, c, len;
56                 unsigned int cur_resol;
57
58                 bezt_curr = &point->bezt;
59                 bezt_next = BKE_mask_spline_point_next_bezt(spline, spline->points, point);
60
61                 if (bezt_next == NULL) {
62                         break;
63                 }
64
65                 a = len_v3v3(bezt_curr->vec[1], bezt_curr->vec[2]);
66                 b = len_v3v3(bezt_curr->vec[2], bezt_next->vec[0]);
67                 c = len_v3v3(bezt_next->vec[0], bezt_next->vec[1]);
68
69                 len = a + b + c;
70                 cur_resol = len / max_segment;
71
72                 resol = MAX2(resol, cur_resol);
73
74                 if (resol >= MASK_RESOL_MAX) {
75                         break;
76                 }
77         }
78
79         return CLAMPIS(resol, 1, MASK_RESOL_MAX);
80 }
81
82 unsigned int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height)
83 {
84         const float max_segment = 0.005;
85         unsigned int resol = BKE_mask_spline_resolution(spline, width, height);
86         float max_jump = 0.0f;
87         int i;
88
89         /* avoid checking the featrher if we already hit the maximum value */
90         if (resol >= MASK_RESOL_MAX) {
91                 return MASK_RESOL_MAX;
92         }
93
94         for (i = 0; i < spline->tot_point; i++) {
95                 MaskSplinePoint *point = &spline->points[i];
96                 float prev_u, prev_w;
97                 int j;
98
99                 prev_u = 0.0f;
100                 prev_w = point->bezt.weight;
101
102                 for (j = 0; j < point->tot_uw; j++) {
103                         const float w_diff = (point->uw[j].w - prev_w);
104                         const float u_diff = (point->uw[j].u - prev_u);
105
106                         /* avoid divide by zero and very high values,
107                          * though these get clamped eventually */
108                         if (u_diff > FLT_EPSILON) {
109                                 float jump = fabsf(w_diff / u_diff);
110
111                                 max_jump = max_ff(max_jump, jump);
112                         }
113
114                         prev_u = point->uw[j].u;
115                         prev_w = point->uw[j].w;
116                 }
117         }
118
119         resol += max_jump / max_segment;
120
121         return CLAMPIS(resol, 1, MASK_RESOL_MAX);
122 }
123
124 int BKE_mask_spline_differentiate_calc_total(const MaskSpline *spline, const unsigned int resol)
125 {
126         if (spline->flag & MASK_SPLINE_CYCLIC) {
127                 return spline->tot_point * resol;
128         }
129         else {
130                 return ((spline->tot_point - 1) * resol) + 1;
131         }
132 }
133
134 float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline,
135                                                       unsigned int *tot_diff_point,
136                                                       const unsigned int resol
137                                                       ))[2]
138 {
139         MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
140
141         MaskSplinePoint *point_curr, *point_prev;
142         float (*diff_points)[2], (*fp)[2];
143         const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol);
144         int a;
145
146         if (spline->tot_point <= 1) {
147                 /* nothing to differentiate */
148                 *tot_diff_point = 0;
149                 return NULL;
150         }
151
152         /* len+1 because of 'forward_diff_bezier' function */
153         *tot_diff_point = tot;
154         diff_points = fp = MEM_mallocN((tot + 1) * sizeof(*diff_points), "mask spline vets");
155
156         a = spline->tot_point - 1;
157         if (spline->flag & MASK_SPLINE_CYCLIC)
158                 a++;
159
160         point_prev = points_array;
161         point_curr = point_prev + 1;
162
163         while (a--) {
164                 BezTriple *bezt_prev;
165                 BezTriple *bezt_curr;
166                 int j;
167
168                 if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC))
169                         point_curr = points_array;
170
171                 bezt_prev = &point_prev->bezt;
172                 bezt_curr = &point_curr->bezt;
173
174                 for (j = 0; j < 2; j++) {
175                         BKE_curve_forward_diff_bezier(bezt_prev->vec[1][j], bezt_prev->vec[2][j],
176                                                       bezt_curr->vec[0][j], bezt_curr->vec[1][j],
177                                                       &(*fp)[j], resol, 2 * sizeof(float));
178                 }
179
180                 fp += resol;
181
182                 if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) {
183                         copy_v2_v2(*fp, bezt_curr->vec[1]);
184                 }
185
186                 point_prev = point_curr;
187                 point_curr++;
188         }
189
190         return diff_points;
191 }
192
193 float (*BKE_mask_spline_differentiate(MaskSpline *spline, int width, int height,
194                                       unsigned int *tot_diff_point
195                                       ))[2]
196 {
197         int unsigned resol = BKE_mask_spline_resolution(spline, width, height);
198
199         return BKE_mask_spline_differentiate_with_resolution(spline, tot_diff_point, resol);
200 }
201
202 /* ** feather points self-intersection collapse routine ** */
203
204 typedef struct FeatherEdgesBucket {
205         int tot_segment;
206         int (*segments)[2];
207         int alloc_segment;
208 } FeatherEdgesBucket;
209
210 static void feather_bucket_add_edge(FeatherEdgesBucket *bucket, int start, int end)
211 {
212         const int alloc_delta = 256;
213
214         if (bucket->tot_segment >= bucket->alloc_segment) {
215                 if (!bucket->segments) {
216                         bucket->segments = MEM_callocN(alloc_delta * sizeof(*bucket->segments), "feather bucket segments");
217                 }
218                 else {
219                         bucket->segments = MEM_reallocN(bucket->segments,
220                                                         (alloc_delta + bucket->tot_segment) * sizeof(*bucket->segments));
221                 }
222
223                 bucket->alloc_segment += alloc_delta;
224         }
225
226         bucket->segments[bucket->tot_segment][0] = start;
227         bucket->segments[bucket->tot_segment][1] = end;
228
229         bucket->tot_segment++;
230 }
231
232 static void feather_bucket_check_intersect(
233         float (*feather_points)[2], int tot_feather_point, FeatherEdgesBucket *bucket,
234         int cur_a, int cur_b)
235 {
236         int i;
237
238         const float *v1 = (float *) feather_points[cur_a];
239         const float *v2 = (float *) feather_points[cur_b];
240
241         for (i = 0; i < bucket->tot_segment; i++) {
242                 int check_a = bucket->segments[i][0];
243                 int check_b = bucket->segments[i][1];
244
245                 const float *v3 = (float *) feather_points[check_a];
246                 const float *v4 = (float *) feather_points[check_b];
247
248                 if (check_a >= cur_a - 1 || cur_b == check_a)
249                         continue;
250
251                 if (isect_seg_seg_v2_simple(v1, v2, v3, v4)) {
252                         int k;
253                         float p[2];
254                         float min_a[2], max_a[2];
255                         float min_b[2], max_b[2];
256
257                         isect_seg_seg_v2_point(v1, v2, v3, v4, p);
258
259                         INIT_MINMAX2(min_a, max_a);
260                         INIT_MINMAX2(min_b, max_b);
261
262                         /* collapse loop with smaller AABB */
263                         for (k = 0; k < tot_feather_point; k++) {
264                                 if (k >= check_b && k <= cur_a) {
265                                         minmax_v2v2_v2(min_a, max_a, feather_points[k]);
266                                 }
267                                 else {
268                                         minmax_v2v2_v2(min_b, max_b, feather_points[k]);
269                                 }
270                         }
271
272                         if (max_a[0] - min_a[0] < max_b[0] - min_b[0] ||
273                             max_a[1] - min_a[1] < max_b[1] - min_b[1])
274                         {
275                                 for (k = check_b; k <= cur_a; k++) {
276                                         copy_v2_v2(feather_points[k], p);
277                                 }
278                         }
279                         else {
280                                 for (k = 0; k <= check_a; k++) {
281                                         copy_v2_v2(feather_points[k], p);
282                                 }
283
284                                 if (cur_b != 0) {
285                                         for (k = cur_b; k < tot_feather_point; k++) {
286                                                 copy_v2_v2(feather_points[k], p);
287                                         }
288                                 }
289                         }
290                 }
291         }
292 }
293
294 static int feather_bucket_index_from_coord(
295         const float co[2], const float min[2], const float bucket_scale[2],
296         const int buckets_per_side)
297 {
298         int x = (int) ((co[0] - min[0]) * bucket_scale[0]);
299         int y = (int) ((co[1] - min[1]) * bucket_scale[1]);
300
301         if (x == buckets_per_side)
302                 x--;
303
304         if (y == buckets_per_side)
305                 y--;
306
307         return y * buckets_per_side + x;
308 }
309
310 static void feather_bucket_get_diagonal(
311         FeatherEdgesBucket *buckets, int start_bucket_index, int end_bucket_index, int buckets_per_side,
312         FeatherEdgesBucket **r_diagonal_bucket_a, FeatherEdgesBucket **r_diagonal_bucket_b)
313 {
314         int start_bucket_x = start_bucket_index % buckets_per_side;
315         int start_bucket_y = start_bucket_index / buckets_per_side;
316
317         int end_bucket_x = end_bucket_index % buckets_per_side;
318         int end_bucket_y = end_bucket_index / buckets_per_side;
319
320         int diagonal_bucket_a_index = start_bucket_y * buckets_per_side + end_bucket_x;
321         int diagonal_bucket_b_index = end_bucket_y * buckets_per_side + start_bucket_x;
322
323         *r_diagonal_bucket_a = &buckets[diagonal_bucket_a_index];
324         *r_diagonal_bucket_b = &buckets[diagonal_bucket_b_index];
325 }
326
327 void BKE_mask_spline_feather_collapse_inner_loops(
328         MaskSpline *spline, float (*feather_points)[2], const unsigned int tot_feather_point)
329 {
330 #define BUCKET_INDEX(co) \
331         feather_bucket_index_from_coord(co, min, bucket_scale, buckets_per_side)
332
333         int buckets_per_side, tot_bucket;
334         float bucket_size, bucket_scale[2];
335
336         FeatherEdgesBucket *buckets;
337
338         unsigned int i;
339         float min[2], max[2];
340         float max_delta_x = -1.0f, max_delta_y = -1.0f, max_delta;
341
342         if (tot_feather_point < 4) {
343                 /* self-intersection works only for quads at least,
344                  * in other cases polygon can't be self-intersecting anyway
345                  */
346
347                 return;
348         }
349
350         /* find min/max corners of mask to build buckets in that space */
351         INIT_MINMAX2(min, max);
352
353         for (i = 0; i < tot_feather_point; i++) {
354                 unsigned int next = i + 1;
355                 float delta;
356
357                 minmax_v2v2_v2(min, max, feather_points[i]);
358
359                 if (next == tot_feather_point) {
360                         if (spline->flag & MASK_SPLINE_CYCLIC)
361                                 next = 0;
362                         else
363                                 break;
364                 }
365
366                 delta = fabsf(feather_points[i][0] - feather_points[next][0]);
367                 if (delta > max_delta_x)
368                         max_delta_x = delta;
369
370                 delta = fabsf(feather_points[i][1] - feather_points[next][1]);
371                 if (delta > max_delta_y)
372                         max_delta_y = delta;
373         }
374
375         /* prevent divisionsby zero by ensuring bounding box is not collapsed */
376         if (max[0] - min[0] < FLT_EPSILON) {
377                 max[0] += 0.01f;
378                 min[0] -= 0.01f;
379         }
380
381         if (max[1] - min[1] < FLT_EPSILON) {
382                 max[1] += 0.01f;
383                 min[1] -= 0.01f;
384         }
385
386         /* use dynamically calculated buckets per side, so we likely wouldn't
387          * run into a situation when segment doesn't fit two buckets which is
388          * pain collecting candidates for intersection
389          */
390
391         max_delta_x /= max[0] - min[0];
392         max_delta_y /= max[1] - min[1];
393
394         max_delta = MAX2(max_delta_x, max_delta_y);
395
396         buckets_per_side = min_ii(512, 0.9f / max_delta);
397
398         if (buckets_per_side == 0) {
399                 /* happens when some segment fills the whole bounding box across some of dimension */
400
401                 buckets_per_side = 1;
402         }
403
404         tot_bucket = buckets_per_side * buckets_per_side;
405         bucket_size = 1.0f / buckets_per_side;
406
407         /* pre-compute multipliers, to save mathematical operations in loops */
408         bucket_scale[0] = 1.0f / ((max[0] - min[0]) * bucket_size);
409         bucket_scale[1] = 1.0f / ((max[1] - min[1]) * bucket_size);
410
411         /* fill in buckets' edges */
412         buckets = MEM_callocN(sizeof(FeatherEdgesBucket) * tot_bucket, "feather buckets");
413
414         for (i = 0; i < tot_feather_point; i++) {
415                 int start = i, end = i + 1;
416                 int start_bucket_index, end_bucket_index;
417
418                 if (end == tot_feather_point) {
419                         if (spline->flag & MASK_SPLINE_CYCLIC)
420                                 end = 0;
421                         else
422                                 break;
423                 }
424
425                 start_bucket_index = BUCKET_INDEX(feather_points[start]);
426                 end_bucket_index = BUCKET_INDEX(feather_points[end]);
427
428                 feather_bucket_add_edge(&buckets[start_bucket_index], start, end);
429
430                 if (start_bucket_index != end_bucket_index) {
431                         FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index];
432                         FeatherEdgesBucket *diagonal_bucket_a, *diagonal_bucket_b;
433
434                         feather_bucket_get_diagonal(buckets, start_bucket_index, end_bucket_index, buckets_per_side,
435                                                     &diagonal_bucket_a, &diagonal_bucket_b);
436
437                         feather_bucket_add_edge(end_bucket, start, end);
438                         feather_bucket_add_edge(diagonal_bucket_a, start, end);
439                         feather_bucket_add_edge(diagonal_bucket_a, start, end);
440                 }
441         }
442
443         /* check all edges for intersection with edges from their buckets */
444         for (i = 0; i < tot_feather_point; i++) {
445                 int cur_a = i, cur_b = i + 1;
446                 int start_bucket_index, end_bucket_index;
447
448                 FeatherEdgesBucket *start_bucket;
449
450                 if (cur_b == tot_feather_point)
451                         cur_b = 0;
452
453                 start_bucket_index = BUCKET_INDEX(feather_points[cur_a]);
454                 end_bucket_index = BUCKET_INDEX(feather_points[cur_b]);
455
456                 start_bucket = &buckets[start_bucket_index];
457
458                 feather_bucket_check_intersect(feather_points, tot_feather_point, start_bucket, cur_a, cur_b);
459
460                 if (start_bucket_index != end_bucket_index) {
461                         FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index];
462                         FeatherEdgesBucket *diagonal_bucket_a, *diagonal_bucket_b;
463
464                         feather_bucket_get_diagonal(buckets, start_bucket_index, end_bucket_index, buckets_per_side,
465                                                     &diagonal_bucket_a, &diagonal_bucket_b);
466
467                         feather_bucket_check_intersect(feather_points, tot_feather_point, end_bucket, cur_a, cur_b);
468                         feather_bucket_check_intersect(feather_points, tot_feather_point, diagonal_bucket_a, cur_a, cur_b);
469                         feather_bucket_check_intersect(feather_points, tot_feather_point, diagonal_bucket_b, cur_a, cur_b);
470                 }
471         }
472
473         /* free buckets */
474         for (i = 0; i < tot_bucket; i++) {
475                 if (buckets[i].segments)
476                         MEM_freeN(buckets[i].segments);
477         }
478
479         MEM_freeN(buckets);
480
481 #undef BUCKET_INDEX
482 }
483
484 /** only called from #BKE_mask_spline_feather_differentiated_points_with_resolution() ! */
485 static float (*mask_spline_feather_differentiated_points_with_resolution__even(
486         MaskSpline *spline, unsigned int *tot_feather_point,
487         const unsigned int resol, const bool do_feather_isect))[2]
488 {
489         MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
490         MaskSplinePoint *point_curr, *point_prev;
491         float (*feather)[2], (*fp)[2];
492
493         const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol);
494         int a;
495
496         /* tot+1 because of 'forward_diff_bezier' function */
497         feather = fp = MEM_mallocN((tot + 1) * sizeof(*feather), "mask spline feather diff points");
498
499         a = spline->tot_point - 1;
500         if (spline->flag & MASK_SPLINE_CYCLIC)
501                 a++;
502
503         point_prev = points_array;
504         point_curr = point_prev + 1;
505
506         while (a--) {
507                 /* BezTriple *bezt_prev; */  /* UNUSED */
508                 /* BezTriple *bezt_curr; */      /* UNUSED */
509                 int j;
510
511                 if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC))
512                         point_curr = points_array;
513
514
515                 /* bezt_prev = &point_prev->bezt; */
516                 /* bezt_curr = &point_curr->bezt; */
517
518                 for (j = 0; j < resol; j++, fp++) {
519                         float u = (float) j / resol, weight;
520                         float co[2], n[2];
521
522                         /* TODO - these calls all calculate similar things
523                          * could be unified for some speed */
524                         BKE_mask_point_segment_co(spline, point_prev, u, co);
525                         BKE_mask_point_normal(spline, point_prev, u, n);
526                         weight = BKE_mask_point_weight(spline, point_prev, u);
527
528                         madd_v2_v2v2fl(*fp, co, n, weight);
529                 }
530
531                 if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) {
532                         float u = 1.0f, weight;
533                         float co[2], n[2];
534
535                         BKE_mask_point_segment_co(spline, point_prev, u, co);
536                         BKE_mask_point_normal(spline, point_prev, u, n);
537                         weight = BKE_mask_point_weight(spline, point_prev, u);
538
539                         madd_v2_v2v2fl(*fp, co, n, weight);
540                 }
541
542                 point_prev = point_curr;
543                 point_curr++;
544         }
545
546         *tot_feather_point = tot;
547
548         if ((spline->flag & MASK_SPLINE_NOINTERSECT) && do_feather_isect) {
549                 BKE_mask_spline_feather_collapse_inner_loops(spline, feather, tot);
550         }
551
552         return feather;
553 }
554
555 /** only called from #BKE_mask_spline_feather_differentiated_points_with_resolution() ! */
556 static float (*mask_spline_feather_differentiated_points_with_resolution__double(
557         MaskSpline *spline, unsigned int *tot_feather_point,
558         const unsigned int resol, const bool do_feather_isect))[2]
559 {
560         MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
561
562         MaskSplinePoint *point_curr, *point_prev;
563         float (*feather)[2], (*fp)[2];
564         const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol);
565         int a;
566
567         if (spline->tot_point <= 1) {
568                 /* nothing to differentiate */
569                 *tot_feather_point = 0;
570                 return NULL;
571         }
572
573         /* len+1 because of 'forward_diff_bezier' function */
574         *tot_feather_point = tot;
575         feather = fp = MEM_mallocN((tot + 1) * sizeof(*feather), "mask spline vets");
576
577         a = spline->tot_point - 1;
578         if (spline->flag & MASK_SPLINE_CYCLIC)
579                 a++;
580
581         point_prev = points_array;
582         point_curr = point_prev + 1;
583
584         while (a--) {
585                 BezTriple local_prevbezt;
586                 BezTriple local_bezt;
587                 float point_prev_n[2], point_curr_n[2], tvec[2];
588                 float weight_prev, weight_curr;
589                 float len_base, len_feather, len_scalar;
590
591                 BezTriple *bezt_prev;
592                 BezTriple *bezt_curr;
593                 int j;
594
595                 if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC))
596                         point_curr = points_array;
597
598                 bezt_prev = &point_prev->bezt;
599                 bezt_curr = &point_curr->bezt;
600
601                 /* modified copy for feather */
602                 local_prevbezt = *bezt_prev;
603                 local_bezt     = *bezt_curr;
604
605                 bezt_prev = &local_prevbezt;
606                 bezt_curr = &local_bezt;
607
608                 /* calc the normals */
609                 sub_v2_v2v2(tvec, bezt_prev->vec[1], bezt_prev->vec[0]);
610                 normalize_v2(tvec);
611                 point_prev_n[0] = -tvec[1];
612                 point_prev_n[1] =  tvec[0];
613
614                 sub_v2_v2v2(tvec, bezt_curr->vec[1], bezt_curr->vec[0]);
615                 normalize_v2(tvec);
616                 point_curr_n[0] = -tvec[1];
617                 point_curr_n[1] =  tvec[0];
618
619                 weight_prev = bezt_prev->weight;
620                 weight_curr = bezt_curr->weight;
621
622                 mul_v2_fl(point_prev_n, weight_prev);
623                 mul_v2_fl(point_curr_n, weight_curr);
624
625                 /* before we transform verts */
626                 len_base = len_v2v2(bezt_prev->vec[1], bezt_curr->vec[1]);
627
628                 // add_v2_v2(bezt_prev->vec[0], point_prev_n);  // not needed
629                 add_v2_v2(bezt_prev->vec[1], point_prev_n);
630                 add_v2_v2(bezt_prev->vec[2], point_prev_n);
631
632                 add_v2_v2(bezt_curr->vec[0], point_curr_n);
633                 add_v2_v2(bezt_curr->vec[1], point_curr_n);
634                 // add_v2_v2(bezt_curr->vec[2], point_curr_n); // not needed
635
636                 len_feather = len_v2v2(bezt_prev->vec[1], bezt_curr->vec[1]);
637
638                 /* scale by chane in length */
639                 len_scalar = len_feather / len_base;
640                 dist_ensure_v2_v2fl(bezt_prev->vec[2], bezt_prev->vec[1], len_scalar * len_v2v2(bezt_prev->vec[2], bezt_prev->vec[1]));
641                 dist_ensure_v2_v2fl(bezt_curr->vec[0], bezt_curr->vec[1], len_scalar * len_v2v2(bezt_curr->vec[0], bezt_curr->vec[1]));
642
643
644                 for (j = 0; j < 2; j++) {
645                         BKE_curve_forward_diff_bezier(bezt_prev->vec[1][j], bezt_prev->vec[2][j],
646                                                       bezt_curr->vec[0][j], bezt_curr->vec[1][j],
647                                                       &(*fp)[j], resol, 2 * sizeof(float));
648                 }
649
650
651                 /* scale by the uw's */
652                 if (point_prev->tot_uw) {
653                         for (j = 0; j < resol; j++, fp++) {
654                                 float u = (float) j / resol;
655                                 float weight_uw, weight_scalar;
656                                 float co[2];
657
658                                 /* TODO - these calls all calculate similar things
659                                  * could be unified for some speed */
660                                 BKE_mask_point_segment_co(spline, point_prev, u, co);
661
662                                 weight_uw     = BKE_mask_point_weight(spline, point_prev, u);
663                                 weight_scalar = BKE_mask_point_weight_scalar(spline, point_prev, u);
664
665                                 dist_ensure_v2_v2fl(*fp, co, len_v2v2(*fp, co) * (weight_uw / weight_scalar));
666                         }
667                 }
668                 else {
669                         fp += resol;
670                 }
671
672                 if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) {
673                         copy_v2_v2(*fp, bezt_curr->vec[1]);
674                 }
675
676                 point_prev = point_curr;
677                 point_curr++;
678         }
679
680         if ((spline->flag & MASK_SPLINE_NOINTERSECT) && do_feather_isect) {
681                 BKE_mask_spline_feather_collapse_inner_loops(spline, feather, tot);
682         }
683
684         return feather;
685 }
686
687 /**
688  * values align with #BKE_mask_spline_differentiate_with_resolution
689  * when \a resol arguments match.
690  */
691 float (*BKE_mask_spline_feather_differentiated_points_with_resolution(
692         MaskSpline *spline, unsigned int *tot_feather_point,
693         const unsigned int resol, const bool do_feather_isect))[2]
694 {
695         switch (spline->offset_mode) {
696                 case MASK_SPLINE_OFFSET_EVEN:
697                         return mask_spline_feather_differentiated_points_with_resolution__even(spline, tot_feather_point, resol, do_feather_isect);
698                 case MASK_SPLINE_OFFSET_SMOOTH:
699                 default:
700                         return mask_spline_feather_differentiated_points_with_resolution__double(spline, tot_feather_point, resol, do_feather_isect);
701         }
702 }
703
704 float (*BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point))[2]
705 {
706         MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
707
708         int i, tot = 0;
709         float (*feather)[2], (*fp)[2];
710
711         /* count */
712         for (i = 0; i < spline->tot_point; i++) {
713                 MaskSplinePoint *point = &points_array[i];
714
715                 tot += point->tot_uw + 1;
716         }
717
718         /* create data */
719         feather = fp = MEM_mallocN(tot * sizeof(*feather), "mask spline feather points");
720
721         for (i = 0; i < spline->tot_point; i++) {
722                 MaskSplinePoint *point = &points_array[i];
723                 BezTriple *bezt = &point->bezt;
724                 float weight, n[2];
725                 int j;
726
727                 BKE_mask_point_normal(spline, point, 0.0f, n);
728                 weight = BKE_mask_point_weight(spline, point, 0.0f);
729
730                 madd_v2_v2v2fl(*fp, bezt->vec[1], n, weight);
731                 fp++;
732
733                 for (j = 0; j < point->tot_uw; j++) {
734                         float u = point->uw[j].u;
735                         float co[2];
736
737                         BKE_mask_point_segment_co(spline, point, u, co);
738                         BKE_mask_point_normal(spline, point, u, n);
739                         weight = BKE_mask_point_weight(spline, point, u);
740
741                         madd_v2_v2v2fl(*fp, co, n, weight);
742                         fp++;
743                 }
744         }
745
746         *tot_feather_point = tot;
747
748         return feather;
749 }
750
751 /* *** mask point functions which involve evaluation *** */
752 float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint *point,
753                                            int width, int height,
754                                            unsigned int *tot_feather_point)
755 {
756         float *feather, *fp;
757         unsigned int resol = BKE_mask_spline_feather_resolution(spline, width, height);
758         unsigned int i;
759
760         feather = fp = MEM_callocN(2 * resol * sizeof(float), "mask point spline feather diff points");
761
762         for (i = 0; i < resol; i++, fp += 2) {
763                 float u = (float)(i % resol) / resol, weight;
764                 float co[2], n[2];
765
766                 BKE_mask_point_segment_co(spline, point, u, co);
767                 BKE_mask_point_normal(spline, point, u, n);
768                 weight = BKE_mask_point_weight(spline, point, u);
769
770                 fp[0] = co[0] + n[0] * weight;
771                 fp[1] = co[1] + n[1] * weight;
772         }
773
774         *tot_feather_point = resol;
775
776         return feather;
777 }
778
779 float *BKE_mask_point_segment_diff(MaskSpline *spline, MaskSplinePoint *point,
780                                    int width, int height, unsigned int *tot_diff_point)
781 {
782         MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
783
784         BezTriple *bezt, *bezt_next;
785         float *diff_points, *fp;
786         int j, resol = BKE_mask_spline_resolution(spline, width, height);
787
788         bezt = &point->bezt;
789         bezt_next = BKE_mask_spline_point_next_bezt(spline, points_array, point);
790
791         if (!bezt_next)
792                 return NULL;
793
794         /* resol+1 because of 'forward_diff_bezier' function */
795         *tot_diff_point = resol + 1;
796         diff_points = fp = MEM_callocN((resol + 1) * 2 * sizeof(float), "mask segment vets");
797
798         for (j = 0; j < 2; j++) {
799                 BKE_curve_forward_diff_bezier(bezt->vec[1][j], bezt->vec[2][j],
800                                               bezt_next->vec[0][j], bezt_next->vec[1][j],
801                                               fp + j, resol, 2 * sizeof(float));
802         }
803
804         copy_v2_v2(fp + 2 * resol, bezt_next->vec[1]);
805
806         return diff_points;
807 }
808
809 static void mask_evaluate_apply_point_parent(MaskSplinePoint *point, float ctime)
810 {
811         float parent_matrix[3][3];
812         BKE_mask_point_parent_matrix_get(point, ctime, parent_matrix);
813         mul_m3_v2(parent_matrix, point->bezt.vec[0]);
814         mul_m3_v2(parent_matrix, point->bezt.vec[1]);
815         mul_m3_v2(parent_matrix, point->bezt.vec[2]);
816 }
817
818 void BKE_mask_layer_evaluate_animation(MaskLayer *masklay, const float ctime)
819 {
820         /* animation if available */
821         MaskLayerShape *masklay_shape_a;
822         MaskLayerShape *masklay_shape_b;
823         int found;
824         if ((found = BKE_mask_layer_shape_find_frame_range(
825                 masklay, ctime, &masklay_shape_a, &masklay_shape_b)))
826         {
827                 if (found == 1) {
828 #if 0
829                         printf("%s: exact %d %d (%d)\n",
830                                __func__,
831                                (int)ctime,
832                                BLI_listbase_count(&masklay->splines_shapes),
833                                masklay_shape_a->frame);
834 #endif
835                         BKE_mask_layer_shape_to_mask(masklay, masklay_shape_a);
836                 }
837                 else if (found == 2) {
838                         float w = masklay_shape_b->frame - masklay_shape_a->frame;
839 #if 0
840                         printf("%s: tween %d %d (%d %d)\n",
841                                __func__,
842                                (int)ctime,
843                                BLI_listbase_count(&masklay->splines_shapes),
844                                masklay_shape_a->frame, masklay_shape_b->frame);
845 #endif
846                         BKE_mask_layer_shape_to_mask_interp(
847                                 masklay,
848                                 masklay_shape_a, masklay_shape_b,
849                                 (ctime - masklay_shape_a->frame) / w);
850                 }
851                 else {
852                         /* always fail, should never happen */
853                         BLI_assert(found == 2);
854                 }
855         }
856 }
857
858 void BKE_mask_layer_evaluate_deform(MaskLayer *masklay, const float ctime)
859 {
860         BKE_mask_layer_calc_handles(masklay);
861         for (MaskSpline *spline = masklay->splines.first;
862              spline != NULL;
863              spline = spline->next)
864         {
865                 bool need_handle_recalc = false;
866                 BKE_mask_spline_ensure_deform(spline);
867                 for (int i = 0; i < spline->tot_point; i++) {
868                         MaskSplinePoint *point = &spline->points[i];
869                         MaskSplinePoint *point_deform = &spline->points_deform[i];
870                         BKE_mask_point_free(point_deform);
871                         *point_deform = *point;
872                         point_deform->uw = point->uw ? MEM_dupallocN(point->uw) : NULL;
873                         mask_evaluate_apply_point_parent(point_deform, ctime);
874                         if (ELEM(point->bezt.h1, HD_AUTO, HD_VECT)) {
875                                 need_handle_recalc = true;
876                         }
877                 }
878                 /* if the spline has auto or vector handles, these need to be
879                  * recalculated after deformation.
880                  */
881                 if (need_handle_recalc) {
882                         for (int i = 0; i < spline->tot_point; i++) {
883                                 MaskSplinePoint *point_deform = &spline->points_deform[i];
884                                 if (ELEM(point_deform->bezt.h1, HD_AUTO, HD_VECT)) {
885                                         BKE_mask_calc_handle_point(spline, point_deform);
886                                 }
887                         }
888                 }
889                 /* end extra calc handles loop */
890         }
891 }
892
893 void BKE_mask_eval_animation(struct Depsgraph *depsgraph, Mask *mask)
894 {
895         float ctime = DEG_get_ctime(depsgraph);
896         DEG_debug_print_eval(depsgraph, __func__, mask->id.name, mask);
897         for (MaskLayer *mask_layer = mask->masklayers.first;
898              mask_layer != NULL;
899              mask_layer = mask_layer->next)
900         {
901                 BKE_mask_layer_evaluate_animation(mask_layer, ctime);
902         }
903 }
904
905 void BKE_mask_eval_update(struct Depsgraph *depsgraph, Mask *mask)
906 {
907         float ctime = DEG_get_ctime(depsgraph);
908         DEG_debug_print_eval(depsgraph, __func__, mask->id.name, mask);
909         for (MaskLayer *mask_layer = mask->masklayers.first;
910              mask_layer != NULL;
911              mask_layer = mask_layer->next)
912         {
913                 BKE_mask_layer_evaluate_deform(mask_layer, ctime);
914         }
915 }