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