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