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