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