Merging r48992 through r48995 from trunk into soc-2011-tomato
[blender.git] / source / blender / blenkernel / intern / mask.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  *
24  * ***** END GPL LICENSE BLOCK *****
25  */
26
27 /** \file blender/blenkernel/intern/mask.c
28  *  \ingroup bke
29  */
30
31 #include <stddef.h>
32 #include <string.h>
33
34 #include "MEM_guardedalloc.h"
35
36 #include "BLI_utildefines.h"
37 #include "BLI_path_util.h"
38 #include "BLI_string.h"
39 #include "BLI_listbase.h"
40 #include "BLI_math.h"
41
42 #include "DNA_mask_types.h"
43 #include "DNA_scene_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_screen_types.h"
46 #include "DNA_space_types.h"
47 #include "DNA_movieclip_types.h"
48 #include "DNA_tracking_types.h"
49
50 #include "BKE_curve.h"
51 #include "BKE_global.h"
52 #include "BKE_library.h"
53 #include "BKE_main.h"
54 #include "BKE_mask.h"
55 #include "BKE_tracking.h"
56 #include "BKE_movieclip.h"
57 #include "BKE_utildefines.h"
58
59 #include "raskter.h"
60
61 #ifdef USE_MANGO_MASK_CACHE_HACK
62
63 #include "BLI_threads.h"
64
65 typedef struct MaskRasterCache {
66         float *buffer;
67         int width, height;
68         short do_aspect_correct;
69         short do_mask_aa;
70         short do_feather;
71
72         ListBase layers;
73 } MaskRasterCache;
74 #endif
75
76 static MaskSplinePoint *mask_spline_point_next(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point)
77 {
78         if (point == &points_array[spline->tot_point - 1]) {
79                 if (spline->flag & MASK_SPLINE_CYCLIC) {
80                         return &points_array[0];
81                 }
82                 else {
83                         return NULL;
84                 }
85         }
86         else {
87                 return point + 1;
88         }
89 }
90
91 static MaskSplinePoint *mask_spline_point_prev(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point)
92 {
93         if (point == points_array) {
94                 if (spline->flag & MASK_SPLINE_CYCLIC) {
95                         return &points_array[spline->tot_point - 1];
96                 }
97                 else {
98                         return NULL;
99                 }
100         }
101         else {
102                 return point - 1;
103         }
104 }
105
106 static BezTriple *mask_spline_point_next_bezt(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point)
107 {
108         if (point == &points_array[spline->tot_point - 1]) {
109                 if (spline->flag & MASK_SPLINE_CYCLIC) {
110                         return &(points_array[0].bezt);
111                 }
112                 else {
113                         return NULL;
114                 }
115         }
116         else {
117                 return &((point + 1))->bezt;
118         }
119 }
120
121 #if 0
122 static BezTriple *mask_spline_point_prev_bezt(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point)
123 {
124         if (point == points_array) {
125                 if (spline->flag & MASK_SPLINE_CYCLIC) {
126                         return &(points_array[0].bezt);
127                 }
128                 else  {
129                         return NULL;
130                 }
131         }
132         else {
133                 return &((point - 1))->bezt;
134         }
135 }
136 #endif
137
138 MaskSplinePoint *BKE_mask_spline_point_array(MaskSpline *spline)
139 {
140         return spline->points_deform ? spline->points_deform : spline->points;
141 }
142
143 MaskSplinePoint *BKE_mask_spline_point_array_from_point(MaskSpline *spline, MaskSplinePoint *point_ref)
144 {
145         if ((point_ref >= spline->points) && (point_ref < &spline->points[spline->tot_point])) {
146                 return spline->points;
147         }
148
149         if ((point_ref >= spline->points_deform) && (point_ref < &spline->points_deform[spline->tot_point])) {
150                 return spline->points_deform;
151         }
152
153         BLI_assert(!"wrong array");
154         return NULL;
155 }
156
157 /* mask layers */
158
159 MaskLayer *BKE_mask_layer_new(Mask *mask, const char *name)
160 {
161         MaskLayer *masklay = MEM_callocN(sizeof(MaskLayer), __func__);
162
163         if (name && name[0])
164                 BLI_strncpy(masklay->name, name, sizeof(masklay->name));
165         else
166                 strcpy(masklay->name, "MaskLayer");
167
168         BLI_addtail(&mask->masklayers, masklay);
169
170         BKE_mask_layer_unique_name(mask, masklay);
171
172         mask->masklay_tot++;
173
174         masklay->alpha = 1.0f;
175
176         return masklay;
177 }
178
179 /* note: may still be hidden, caller needs to check */
180 MaskLayer *BKE_mask_layer_active(Mask *mask)
181 {
182         return BLI_findlink(&mask->masklayers, mask->masklay_act);
183 }
184
185 void BKE_mask_layer_active_set(Mask *mask, MaskLayer *masklay)
186 {
187         mask->masklay_act = BLI_findindex(&mask->masklayers, masklay);
188 }
189
190 void BKE_mask_layer_remove(Mask *mask, MaskLayer *masklay)
191 {
192         BLI_remlink(&mask->masklayers, masklay);
193         BKE_mask_layer_free(masklay);
194
195         mask->masklay_tot--;
196
197         if (mask->masklay_act >= mask->masklay_tot)
198                 mask->masklay_act = mask->masklay_tot - 1;
199 }
200
201 void BKE_mask_layer_unique_name(Mask *mask, MaskLayer *masklay)
202 {
203         BLI_uniquename(&mask->masklayers, masklay, "MaskLayer", '.', offsetof(MaskLayer, name), sizeof(masklay->name));
204 }
205
206 MaskLayer *BKE_mask_layer_copy(MaskLayer *layer)
207 {
208         MaskLayer *layer_new;
209         MaskSpline *spline;
210
211         layer_new = MEM_callocN(sizeof(MaskLayer), "new mask layer");
212
213         BLI_strncpy(layer_new->name, layer->name, sizeof(layer_new->name));
214
215         layer_new->alpha = layer->alpha;
216         layer_new->blend = layer->blend;
217         layer_new->blend_flag = layer->blend_flag;
218         layer_new->flag = layer->flag;
219         layer_new->restrictflag = layer->restrictflag;
220
221         for (spline = layer->splines.first; spline; spline = spline->next) {
222                 MaskSpline *spline_new = BKE_mask_spline_copy(spline);
223
224                 BLI_addtail(&layer_new->splines, spline_new);
225         }
226
227         return layer_new;
228 }
229
230 void BKE_mask_layer_copy_list(ListBase *masklayers_new, ListBase *masklayers)
231 {
232         MaskLayer *layer;
233
234         for (layer = masklayers->first; layer; layer = layer->next) {
235                 MaskLayer *layer_new = BKE_mask_layer_copy(layer);
236
237                 BLI_addtail(masklayers_new, layer_new);
238         }
239 }
240
241 /* splines */
242
243 MaskSpline *BKE_mask_spline_add(MaskLayer *masklay)
244 {
245         MaskSpline *spline;
246
247         spline = MEM_callocN(sizeof(MaskSpline), "new mask spline");
248         BLI_addtail(&masklay->splines, spline);
249
250         /* spline shall have one point at least */
251         spline->points = MEM_callocN(sizeof(MaskSplinePoint), "new mask spline point");
252         spline->tot_point = 1;
253
254         /* cyclic shapes are more usually used */
255         // spline->flag |= MASK_SPLINE_CYCLIC; // disable because its not so nice for drawing. could be done differently
256
257         spline->weight_interp = MASK_SPLINE_INTERP_EASE;
258
259         BKE_mask_parent_init(&spline->parent);
260
261         return spline;
262 }
263
264 int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height)
265 {
266         float max_segment = 0.01f;
267         int i, resol = 1;
268
269         if (width != 0 && height != 0) {
270                 if (width >= height)
271                         max_segment = 1.0f / (float) width;
272                 else
273                         max_segment = 1.0f / (float) height;
274         }
275
276         for (i = 0; i < spline->tot_point; i++) {
277                 MaskSplinePoint *point = &spline->points[i];
278                 BezTriple *bezt, *bezt_next;
279                 float a, b, c, len;
280                 int cur_resol;
281
282                 bezt = &point->bezt;
283                 bezt_next = mask_spline_point_next_bezt(spline, spline->points, point);
284
285                 if (bezt_next == NULL) {
286                         break;
287                 }
288
289                 a = len_v3v3(bezt->vec[1], bezt->vec[2]);
290                 b = len_v3v3(bezt->vec[2], bezt_next->vec[0]);
291                 c = len_v3v3(bezt_next->vec[0], bezt_next->vec[1]);
292
293                 len = a + b + c;
294                 cur_resol = len / max_segment;
295
296                 resol = MAX2(resol, cur_resol);
297         }
298
299         return resol;
300 }
301
302 int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height)
303 {
304         const float max_segment = 0.005;
305         int resol = BKE_mask_spline_resolution(spline, width, height);
306         float max_jump = 0.0f;
307         int i;
308
309         for (i = 0; i < spline->tot_point; i++) {
310                 MaskSplinePoint *point = &spline->points[i];
311                 float prev_u, prev_w;
312                 int j;
313
314                 prev_u = 0.0f;
315                 prev_w = point->bezt.weight;
316
317                 for (j = 0; j < point->tot_uw; j++) {
318                         float jump = fabsf((point->uw[j].w - prev_w) / (point->uw[j].u - prev_u));
319
320                         max_jump = MAX2(max_jump, jump);
321
322                         prev_u = point->uw[j].u;
323                         prev_w = point->uw[j].w;
324                 }
325         }
326
327         resol += max_jump / max_segment;
328
329         return resol;
330 }
331
332 int BKE_mask_spline_differentiate_calc_total(const MaskSpline *spline, const int resol)
333 {
334         int len;
335
336         /* count */
337         len = (spline->tot_point - 1) * resol;
338
339         if (spline->flag & MASK_SPLINE_CYCLIC) {
340                 len += resol;
341         }
342         else {
343                 len++;
344         }
345
346         return len;
347 }
348
349 float (*BKE_mask_spline_differentiate_with_resolution_ex(MaskSpline *spline,
350                                                          int *tot_diff_point,
351                                                          const int resol
352                                                          ))[2]
353 {
354         MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
355
356         MaskSplinePoint *point, *prev;
357         float (*diff_points)[2], (*fp)[2];
358         const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol);
359         int a;
360
361         if (spline->tot_point <= 1) {
362                 /* nothing to differentiate */
363                 *tot_diff_point = 0;
364                 return NULL;
365         }
366
367         /* len+1 because of 'forward_diff_bezier' function */
368         *tot_diff_point = tot;
369         diff_points = fp = MEM_mallocN((tot + 1) * sizeof(*diff_points), "mask spline vets");
370
371         a = spline->tot_point - 1;
372         if (spline->flag & MASK_SPLINE_CYCLIC)
373                 a++;
374
375         prev = points_array;
376         point = prev + 1;
377
378         while (a--) {
379                 BezTriple *prevbezt;
380                 BezTriple *bezt;
381                 int j;
382
383                 if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC))
384                         point = points_array;
385
386                 prevbezt = &prev->bezt;
387                 bezt = &point->bezt;
388
389                 for (j = 0; j < 2; j++) {
390                         BKE_curve_forward_diff_bezier(prevbezt->vec[1][j], prevbezt->vec[2][j],
391                                                       bezt->vec[0][j], bezt->vec[1][j],
392                                                       &(*fp)[j], resol, 2 * sizeof(float));
393                 }
394
395                 fp += resol;
396
397                 if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) {
398                         copy_v2_v2(*fp, bezt->vec[1]);
399                 }
400
401                 prev = point;
402                 point++;
403         }
404
405         return diff_points;
406 }
407
408 float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline, int width, int height,
409                                                       int *tot_diff_point
410                                                       ))[2]
411 {
412         int resol = BKE_mask_spline_resolution(spline, width, height);
413
414         return BKE_mask_spline_differentiate_with_resolution_ex(spline, tot_diff_point, resol);
415 }
416
417 float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point))[2]
418 {
419         return BKE_mask_spline_differentiate_with_resolution(spline, 0, 0, tot_diff_point);
420 }
421
422 /* ** feather points self-intersection collapse routine ** */
423
424 typedef struct FeatherEdgesBucket {
425         int tot_segment;
426         int (*segments)[2];
427         int alloc_segment;
428 } FeatherEdgesBucket;
429
430 static void feather_bucket_add_edge(FeatherEdgesBucket *bucket, int start, int end)
431 {
432         const int alloc_delta = 32;
433
434         if (bucket->tot_segment >= bucket->alloc_segment) {
435                 if (!bucket->segments) {
436                         bucket->segments = MEM_callocN(alloc_delta * sizeof(*bucket->segments), "feather bucket segments");
437                 }
438                 else {
439                         bucket->segments = MEM_reallocN(bucket->segments,
440                                         (alloc_delta + bucket->tot_segment) * sizeof(*bucket->segments));
441                 }
442
443                 bucket->alloc_segment += alloc_delta;
444         }
445
446         bucket->segments[bucket->tot_segment][0] = start;
447         bucket->segments[bucket->tot_segment][1] = end;
448
449         bucket->tot_segment++;
450 }
451
452 static void feather_bucket_check_intersect(float (*feather_points)[2], int tot_feather_point, FeatherEdgesBucket *bucket,
453                                            int cur_a, int cur_b)
454 {
455         int i;
456
457         float *v1 = (float *) feather_points[cur_a];
458         float *v2 = (float *) feather_points[cur_b];
459
460         for (i = 0; i< bucket->tot_segment; i++) {
461                 int check_a = bucket->segments[i][0];
462                 int check_b = bucket->segments[i][1];
463
464                 float *v3 = (float *) feather_points[check_a];
465                 float *v4 = (float *) feather_points[check_b];
466
467                 if (check_a >= cur_a - 1 || cur_b == check_a)
468                         continue;
469
470                 if (isect_seg_seg_v2(v1, v2, v3, v4)) {
471                         int k, len;
472                         float p[2];
473
474                         isect_seg_seg_v2_point(v1, v2, v3, v4, p);
475
476                         /* TODO: for now simply choose the shortest loop, could be made smarter in some way */
477                         len = cur_a - check_b;
478                         if (len < tot_feather_point - len) {
479                                 for (k = check_b; k <= cur_a; k++) {
480                                         copy_v2_v2(feather_points[k], p);
481                                 }
482                         }
483                         else {
484                                 for (k = 0; k <= check_a; k++) {
485                                         copy_v2_v2(feather_points[k], p);
486                                 }
487
488                                 if (cur_b != 0) {
489                                         for (k = cur_b; k < tot_feather_point; k++) {
490                                                 copy_v2_v2(feather_points[k], p);
491                                         }
492                                 }
493                         }
494                 }
495         }
496 }
497
498 static int feather_bucket_index_from_coord(float co[2], float min[2], float max[2],
499                                            const int buckets_per_side, const float bucket_size)
500 {
501 #define BUCKET_SIDE_INDEX(co, min, max) ((int) ((co - min) / (max - min) / bucket_size))
502
503         int x = BUCKET_SIDE_INDEX(co[0], min[0], max[0]);
504         int y = BUCKET_SIDE_INDEX(co[1], min[1], max[1]);
505
506         x = MIN2(x, buckets_per_side - 1);
507         y = MIN2(y, buckets_per_side - 1);
508
509         return y * buckets_per_side + x;
510 #undef BUCKET_SIDE_INDEX
511 }
512
513 static void spline_feather_collapse_inner_loops(float (*feather_points)[2], int tot_feather_point)
514 {
515 #define BUCKET_INDEX(co) \
516         feather_bucket_index_from_coord(co, min, max, buckets_per_side, bucket_size)
517
518         const int buckets_per_side = 10;
519         const int tot_bucket = buckets_per_side * buckets_per_side;
520         const float bucket_size = 1.0f / buckets_per_side;
521
522         FeatherEdgesBucket *buckets;
523
524         int i;
525         float min[2], max[2];
526
527         if (tot_feather_point < 4) {
528                 /* self-intersection works only for quads at least,
529                  * in other cases polygon can't be self-intersecting anyway
530                  */
531
532                 return;
533         }
534
535         /* find min/max corners of mask to build buckets in that space */
536         INIT_MINMAX2(min, max);
537
538         for (i = 0; i < tot_feather_point; i++) {
539                 DO_MINMAX2(feather_points[i], min, max);
540         }
541
542         /* fill in buckets' edges */
543         buckets = MEM_callocN(sizeof(FeatherEdgesBucket) * tot_bucket, "feather buckets");
544
545         for (i = 0; i < tot_feather_point; i++) {
546                 int start = i;
547                 int end = (i + 1) % tot_feather_point;
548
549                 int start_bucket_index = BUCKET_INDEX(feather_points[start]);
550                 int end_bucket_index = BUCKET_INDEX(feather_points[end]);
551
552                 feather_bucket_add_edge(&buckets[start_bucket_index], start, end);
553
554                 if (start_bucket_index != end_bucket_index) {
555                         feather_bucket_add_edge(&buckets[end_bucket_index], start, end);
556                 }
557         }
558
559         /* check all edges for intersection with edges from their buckets */
560         for (i = 0; i < tot_feather_point; i++) {
561                 int cur_a = i;
562                 int cur_b = (i + 1) % tot_feather_point;
563
564                 int start_bucket_index = BUCKET_INDEX(feather_points[cur_a]);
565                 int end_bucket_index = BUCKET_INDEX(feather_points[cur_b]);
566
567                 FeatherEdgesBucket *start_bucket = &buckets[start_bucket_index];
568                 FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index];
569
570                 feather_bucket_check_intersect(feather_points, tot_feather_point, start_bucket, cur_a, cur_b);
571
572                 if (start_bucket != end_bucket)
573                         feather_bucket_check_intersect(feather_points, tot_feather_point, end_bucket, cur_a, cur_b);
574         }
575
576         /* free buckets */
577         for (i = 0; i < tot_bucket; i++) {
578                 if (buckets[i].segments)
579                         MEM_freeN(buckets[i].segments);
580         }
581
582         MEM_freeN(buckets);
583
584 #undef BUCKET_INDEX
585 }
586
587 /**
588  * values align with #BKE_mask_spline_differentiate_with_resolution_ex
589  * when \a resol arguments match.
590  */
591 float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpline *spline,
592                                                                          int *tot_feather_point,
593                                                                          const int resol,
594                                                                          const int do_collapse
595                                                                          ))[2]
596 {
597         MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
598         MaskSplinePoint *point, *prev;
599         float (*feather)[2], (*fp)[2];
600
601         const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol);
602         int a;
603
604         /* tot+1 because of 'forward_diff_bezier' function */
605         feather = fp = MEM_mallocN((tot + 1) * sizeof(*feather), "mask spline feather diff points");
606
607         a = spline->tot_point - 1;
608         if (spline->flag & MASK_SPLINE_CYCLIC)
609                 a++;
610
611         prev = points_array;
612         point = prev + 1;
613
614         while (a--) {
615                 /* BezTriple *prevbezt; */  /* UNUSED */
616                 /* BezTriple *bezt; */      /* UNUSED */
617                 int j;
618
619                 if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC))
620                         point = points_array;
621
622
623                 /* prevbezt = &prev->bezt; */
624                 /* bezt = &point->bezt; */
625
626                 for (j = 0; j < resol; j++, fp++) {
627                         float u = (float) j / resol, weight;
628                         float co[2], n[2];
629
630                         /* TODO - these calls all calculate similar things
631                          * could be unified for some speed */
632                         BKE_mask_point_segment_co(spline, prev, u, co);
633                         BKE_mask_point_normal(spline, prev, u, n);
634                         weight = BKE_mask_point_weight(spline, prev, u);
635
636                         madd_v2_v2v2fl(*fp, co, n, weight);
637                 }
638
639                 if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) {
640                         float u = 1.0f, weight;
641                         float co[2], n[2];
642
643                         BKE_mask_point_segment_co(spline, prev, u, co);
644                         BKE_mask_point_normal(spline, prev, u, n);
645                         weight = BKE_mask_point_weight(spline, prev, u);
646
647                         madd_v2_v2v2fl(*fp, co, n, weight);
648                 }
649
650                 prev = point;
651                 point++;
652         }
653
654         *tot_feather_point = tot;
655
656         /* this is slow! - don't do on draw */
657         if (do_collapse) {
658                 spline_feather_collapse_inner_loops(feather, tot);
659         }
660
661         return feather;
662 }
663
664 float (*BKE_mask_spline_feather_differentiated_points_with_resolution(MaskSpline *spline, int width, int height,
665                                                                       int *tot_feather_point))[2]
666 {
667         int resol = BKE_mask_spline_feather_resolution(spline, width, height);
668
669         return BKE_mask_spline_feather_differentiated_points_with_resolution_ex(spline, tot_feather_point, resol, FALSE);
670 }
671
672 float (*BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *tot_feather_point))[2]
673 {
674         return BKE_mask_spline_feather_differentiated_points_with_resolution(spline, 0, 0, tot_feather_point);
675 }
676
677 float (*BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point))[2]
678 {
679         MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
680
681         int i, tot = 0;
682         float (*feather)[2], (*fp)[2];
683
684         /* count */
685         for (i = 0; i < spline->tot_point; i++) {
686                 MaskSplinePoint *point = &points_array[i];
687
688                 tot += point->tot_uw + 1;
689         }
690
691         /* create data */
692         feather = fp = MEM_mallocN(tot * sizeof(*feather), "mask spline feather points");
693
694         for (i = 0; i < spline->tot_point; i++) {
695                 MaskSplinePoint *point = &points_array[i];
696                 BezTriple *bezt = &point->bezt;
697                 float weight, n[2];
698                 int j;
699
700                 BKE_mask_point_normal(spline, point, 0.0f, n);
701                 weight = BKE_mask_point_weight(spline, point, 0.0f);
702
703                 madd_v2_v2v2fl(*fp, bezt->vec[1], n, weight);
704                 fp++;
705
706                 for (j = 0; j < point->tot_uw; j++) {
707                         float u = point->uw[j].u;
708                         float co[2];
709
710                         BKE_mask_point_segment_co(spline, point, u, co);
711                         BKE_mask_point_normal(spline, point, u, n);
712                         weight = BKE_mask_point_weight(spline, point, u);
713
714                         madd_v2_v2v2fl(*fp, co, n, weight);
715                         fp++;
716                 }
717         }
718
719         *tot_feather_point = tot;
720
721         return feather;
722 }
723
724 void BKE_mask_point_direction_switch(MaskSplinePoint *point)
725 {
726         const int tot_uw = point->tot_uw;
727         const int tot_uw_half = tot_uw / 2;
728         int i;
729
730         float co_tmp[2];
731
732         /* swap handles */
733         copy_v2_v2(co_tmp, point->bezt.vec[0]);
734         copy_v2_v2(point->bezt.vec[0], point->bezt.vec[2]);
735         copy_v2_v2(point->bezt.vec[2], co_tmp);
736         /* in this case the flags are unlikely to be different but swap anyway */
737         SWAP(char, point->bezt.f1, point->bezt.f3);
738         SWAP(char, point->bezt.h1, point->bezt.h2);
739
740
741         /* swap UW's */
742         if (tot_uw > 1) {
743                 /* count */
744                 for (i = 0; i < tot_uw_half; i++) {
745                         MaskSplinePointUW *uw_a = &point->uw[i];
746                         MaskSplinePointUW *uw_b = &point->uw[tot_uw - (i + 1)];
747                         SWAP(MaskSplinePointUW, *uw_a, *uw_b);
748                 }
749         }
750
751         for (i = 0; i < tot_uw; i++) {
752                 MaskSplinePointUW *uw = &point->uw[i];
753                 uw->u = 1.0f - uw->u;
754         }
755 }
756
757 void BKE_mask_spline_direction_switch(MaskLayer *masklay, MaskSpline *spline)
758 {
759         const int tot_point = spline->tot_point;
760         const int tot_point_half = tot_point / 2;
761         int i, i_prev;
762
763         if (tot_point < 2) {
764                 return;
765         }
766
767         /* count */
768         for (i = 0; i < tot_point_half; i++) {
769                 MaskSplinePoint *point_a = &spline->points[i];
770                 MaskSplinePoint *point_b = &spline->points[tot_point - (i + 1)];
771                 SWAP(MaskSplinePoint, *point_a, *point_b);
772         }
773
774         /* correct UW's */
775         i_prev = tot_point - 1;
776         for (i = 0; i < tot_point; i++) {
777
778                 BKE_mask_point_direction_switch(&spline->points[i]);
779
780                 SWAP(MaskSplinePointUW *, spline->points[i].uw,     spline->points[i_prev].uw);
781                 SWAP(int,                 spline->points[i].tot_uw, spline->points[i_prev].tot_uw);
782
783                 i_prev = i;
784         }
785
786         /* correct animation */
787         if (masklay->splines_shapes.first) {
788                 MaskLayerShape *masklay_shape;
789
790                 const int spline_index = BKE_mask_layer_shape_spline_to_index(masklay, spline);
791
792                 for (masklay_shape = masklay->splines_shapes.first;
793                      masklay_shape;
794                      masklay_shape = masklay_shape->next)
795                 {
796                         MaskLayerShapeElem *fp_arr = (MaskLayerShapeElem *)masklay_shape->data;
797
798                         for (i = 0; i < tot_point_half; i++) {
799                                 MaskLayerShapeElem *fp_a = &fp_arr[spline_index +              (i)     ];
800                                 MaskLayerShapeElem *fp_b = &fp_arr[spline_index + (tot_point - (i + 1))];
801                                 SWAP(MaskLayerShapeElem, *fp_a, *fp_b);
802                         }
803                 }
804         }
805 }
806
807
808 float BKE_mask_spline_project_co(MaskSpline *spline, MaskSplinePoint *point,
809                                  float start_u, const float co[2], const eMaskSign sign)
810 {
811         const float proj_eps         = 1e-3;
812         const float proj_eps_squared = proj_eps * proj_eps;
813         const int N = 1000;
814         float u = -1.0f, du = 1.0f / N, u1 = start_u, u2 = start_u;
815         float ang = -1.0f;
816
817         BLI_assert(ABS(sign) <= 1); /* (-1, 0, 1) */
818
819         while (u1 > 0.0f || u2 < 1.0f) {
820                 float n1[2], n2[2], co1[2], co2[2];
821                 float v1[2], v2[2];
822                 float ang1, ang2;
823
824                 if (u1 >= 0.0f) {
825                         BKE_mask_point_segment_co(spline, point, u1, co1);
826                         BKE_mask_point_normal(spline, point, u1, n1);
827                         sub_v2_v2v2(v1, co, co1);
828
829                         if ((sign == MASK_PROJ_ANY) ||
830                             ((sign == MASK_PROJ_NEG) && (dot_v2v2(v1, n1) <= 0.0f)) ||
831                             ((sign == MASK_PROJ_POS) && (dot_v2v2(v1, n1) >= 0.0f)))
832                         {
833
834                                 if (len_squared_v2(v1) > proj_eps_squared) {
835                                         ang1 = angle_v2v2(v1, n1);
836                                         if (ang1 > M_PI / 2.0f)
837                                                 ang1 = M_PI  - ang1;
838
839                                         if (ang < 0.0f || ang1 < ang) {
840                                                 ang = ang1;
841                                                 u = u1;
842                                         }
843                                 }
844                                 else {
845                                         u = u1;
846                                         break;
847                                 }
848                         }
849                 }
850
851                 if (u2 <= 1.0f) {
852                         BKE_mask_point_segment_co(spline, point, u2, co2);
853                         BKE_mask_point_normal(spline, point, u2, n2);
854                         sub_v2_v2v2(v2, co, co2);
855
856                         if ((sign == MASK_PROJ_ANY) ||
857                             ((sign == MASK_PROJ_NEG) && (dot_v2v2(v2, n2) <= 0.0f)) ||
858                             ((sign == MASK_PROJ_POS) && (dot_v2v2(v2, n2) >= 0.0f)))
859                         {
860
861                                 if (len_squared_v2(v2) > proj_eps_squared) {
862                                         ang2 = angle_v2v2(v2, n2);
863                                         if (ang2 > M_PI / 2.0f)
864                                                 ang2 = M_PI  - ang2;
865
866                                         if (ang2 < ang) {
867                                                 ang = ang2;
868                                                 u = u2;
869                                         }
870                                 }
871                                 else {
872                                         u = u2;
873                                         break;
874                                 }
875                         }
876                 }
877
878                 u1 -= du;
879                 u2 += du;
880         }
881
882         return u;
883 }
884
885 /* point */
886
887 int BKE_mask_point_has_handle(MaskSplinePoint *point)
888 {
889         BezTriple *bezt = &point->bezt;
890
891         return bezt->h1 == HD_ALIGN;
892 }
893
894 void BKE_mask_point_handle(MaskSplinePoint *point, float handle[2])
895 {
896         float vec[2];
897
898         sub_v2_v2v2(vec, point->bezt.vec[0], point->bezt.vec[1]);
899
900         handle[0] = (point->bezt.vec[1][0] + vec[1]);
901         handle[1] = (point->bezt.vec[1][1] - vec[0]);
902 }
903
904 void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], int keep_direction,
905                                float orig_handle[2], float orig_vec[3][3])
906 {
907         BezTriple *bezt = &point->bezt;
908         float v1[2], v2[2], vec[2];
909
910         if (keep_direction) {
911                 sub_v2_v2v2(v1, loc, orig_vec[1]);
912                 sub_v2_v2v2(v2, orig_handle, orig_vec[1]);
913
914                 project_v2_v2v2(vec, v1, v2);
915
916                 if (dot_v2v2(v2, vec) > 0) {
917                         float len = len_v2(vec);
918
919                         sub_v2_v2v2(v1, orig_vec[0], orig_vec[1]);
920
921                         mul_v2_fl(v1, len / len_v2(v1));
922
923                         add_v2_v2v2(bezt->vec[0], bezt->vec[1], v1);
924                         sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v1);
925                 }
926                 else {
927                         copy_v3_v3(bezt->vec[0], bezt->vec[1]);
928                         copy_v3_v3(bezt->vec[2], bezt->vec[1]);
929                 }
930         }
931         else {
932                 sub_v2_v2v2(v1, loc, bezt->vec[1]);
933
934                 v2[0] = -v1[1];
935                 v2[1] =  v1[0];
936
937                 add_v2_v2v2(bezt->vec[0], bezt->vec[1], v2);
938                 sub_v2_v2v2(bezt->vec[2], bezt->vec[1], v2);
939         }
940 }
941
942 float *BKE_mask_point_segment_feather_diff_with_resolution(MaskSpline *spline, MaskSplinePoint *point,
943                                                            int width, int height,
944                                                            int *tot_feather_point)
945 {
946         float *feather, *fp;
947         int i, resol = BKE_mask_spline_feather_resolution(spline, width, height);
948
949         feather = fp = MEM_callocN(2 * resol * sizeof(float), "mask point spline feather diff points");
950
951         for (i = 0; i < resol; i++, fp += 2) {
952                 float u = (float)(i % resol) / resol, weight;
953                 float co[2], n[2];
954
955                 BKE_mask_point_segment_co(spline, point, u, co);
956                 BKE_mask_point_normal(spline, point, u, n);
957                 weight = BKE_mask_point_weight(spline, point, u);
958
959                 fp[0] = co[0] + n[0] * weight;
960                 fp[1] = co[1] + n[1] * weight;
961         }
962
963         *tot_feather_point = resol;
964
965         return feather;
966 }
967
968 float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint *point, int *tot_feather_point)
969 {
970         return BKE_mask_point_segment_feather_diff_with_resolution(spline, point, 0, 0, tot_feather_point);
971 }
972
973 float *BKE_mask_point_segment_diff_with_resolution(MaskSpline *spline, MaskSplinePoint *point,
974                                                    int width, int height, int *tot_diff_point)
975 {
976         MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
977
978         BezTriple *bezt, *bezt_next;
979         float *diff_points, *fp;
980         int j, resol = BKE_mask_spline_resolution(spline, width, height);
981
982         bezt = &point->bezt;
983         bezt_next = mask_spline_point_next_bezt(spline, points_array, point);
984
985         if (!bezt_next)
986                 return NULL;
987
988         /* resol+1 because of 'forward_diff_bezier' function */
989         *tot_diff_point = resol + 1;
990         diff_points = fp = MEM_callocN((resol + 1) * 2 * sizeof(float), "mask segment vets");
991
992         for (j = 0; j < 2; j++) {
993                 BKE_curve_forward_diff_bezier(bezt->vec[1][j], bezt->vec[2][j],
994                                               bezt_next->vec[0][j], bezt_next->vec[1][j],
995                                               fp + j, resol, 2 * sizeof(float));
996         }
997
998         copy_v2_v2(fp + 2 * resol, bezt_next->vec[1]);
999
1000         return diff_points;
1001 }
1002
1003 float *BKE_mask_point_segment_diff(MaskSpline *spline, MaskSplinePoint *point, int *tot_diff_point)
1004 {
1005         return BKE_mask_point_segment_diff_with_resolution(spline, point, 0, 0, tot_diff_point);
1006 }
1007
1008 void BKE_mask_point_segment_co(MaskSpline *spline, MaskSplinePoint *point, float u, float co[2])
1009 {
1010         MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
1011
1012         BezTriple *bezt = &point->bezt, *bezt_next;
1013         float q0[2], q1[2], q2[2], r0[2], r1[2];
1014
1015         bezt_next = mask_spline_point_next_bezt(spline, points_array, point);
1016
1017         if (!bezt_next) {
1018                 copy_v2_v2(co, bezt->vec[1]);
1019                 return;
1020         }
1021
1022         interp_v2_v2v2(q0, bezt->vec[1], bezt->vec[2], u);
1023         interp_v2_v2v2(q1, bezt->vec[2], bezt_next->vec[0], u);
1024         interp_v2_v2v2(q2, bezt_next->vec[0], bezt_next->vec[1], u);
1025
1026         interp_v2_v2v2(r0, q0, q1, u);
1027         interp_v2_v2v2(r1, q1, q2, u);
1028
1029         interp_v2_v2v2(co, r0, r1, u);
1030 }
1031
1032 void BKE_mask_point_normal(MaskSpline *spline, MaskSplinePoint *point, float u, float n[2])
1033 {
1034         MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
1035
1036         BezTriple *bezt = &point->bezt, *bezt_next;
1037         float q0[2], q1[2], q2[2], r0[2], r1[2], vec[2];
1038
1039         bezt_next = mask_spline_point_next_bezt(spline, points_array, point);
1040
1041         if (!bezt_next) {
1042                 BKE_mask_point_handle(point, vec);
1043
1044                 sub_v2_v2v2(n, vec, bezt->vec[1]);
1045                 normalize_v2(n);
1046                 return;
1047         }
1048
1049         interp_v2_v2v2(q0, bezt->vec[1], bezt->vec[2], u);
1050         interp_v2_v2v2(q1, bezt->vec[2], bezt_next->vec[0], u);
1051         interp_v2_v2v2(q2, bezt_next->vec[0], bezt_next->vec[1], u);
1052
1053         interp_v2_v2v2(r0, q0, q1, u);
1054         interp_v2_v2v2(r1, q1, q2, u);
1055
1056         sub_v2_v2v2(vec, r1, r0);
1057
1058         n[0] = -vec[1];
1059         n[1] =  vec[0];
1060
1061         normalize_v2(n);
1062 }
1063
1064 static float mask_point_interp_weight(BezTriple *bezt, BezTriple *bezt_next, const float u)
1065 {
1066         return (bezt->weight * (1.0f - u)) + (bezt_next->weight * u);
1067 }
1068
1069 float BKE_mask_point_weight_scalar(MaskSpline *spline, MaskSplinePoint *point, const float u)
1070 {
1071         MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
1072         BezTriple *bezt = &point->bezt, *bezt_next;
1073
1074         bezt_next = mask_spline_point_next_bezt(spline, points_array, point);
1075
1076         if (!bezt_next) {
1077                 return bezt->weight;
1078         }
1079         else if (u <= 0.0) {
1080                 return bezt->weight;
1081         }
1082         else if (u >= 1.0f) {
1083                 return bezt_next->weight;
1084         }
1085         else {
1086                 return mask_point_interp_weight(bezt, bezt_next, u);
1087         }
1088 }
1089
1090 float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, const float u)
1091 {
1092         MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
1093         BezTriple *bezt = &point->bezt, *bezt_next;
1094
1095         bezt_next = mask_spline_point_next_bezt(spline, points_array, point);
1096
1097         if (!bezt_next) {
1098                 return bezt->weight;
1099         }
1100         else if (u <= 0.0) {
1101                 return bezt->weight;
1102         }
1103         else if (u >= 1.0f) {
1104                 return bezt_next->weight;
1105         }
1106         else {
1107                 float cur_u = 0.0f, cur_w = 0.0f, next_u = 0.0f, next_w = 0.0f, fac; /* Quite warnings */
1108                 int i;
1109
1110                 for (i = 0; i < point->tot_uw + 1; i++) {
1111
1112                         if (i == 0) {
1113                                 cur_u = 0.0f;
1114                                 cur_w = 1.0f; /* mask_point_interp_weight will scale it */
1115                         }
1116                         else {
1117                                 cur_u = point->uw[i - 1].u;
1118                                 cur_w = point->uw[i - 1].w;
1119                         }
1120
1121                         if (i == point->tot_uw) {
1122                                 next_u = 1.0f;
1123                                 next_w = 1.0f; /* mask_point_interp_weight will scale it */
1124                         }
1125                         else {
1126                                 next_u = point->uw[i].u;
1127                                 next_w = point->uw[i].w;
1128                         }
1129
1130                         if (u >= cur_u && u <= next_u) {
1131                                 break;
1132                         }
1133                 }
1134
1135                 fac = (u - cur_u) / (next_u - cur_u);
1136
1137                 cur_w  *= mask_point_interp_weight(bezt, bezt_next, cur_u);
1138                 next_w *= mask_point_interp_weight(bezt, bezt_next, next_u);
1139
1140                 if (spline->weight_interp == MASK_SPLINE_INTERP_EASE) {
1141                         return cur_w + (next_w - cur_w) * (3.0f * fac * fac - 2.0f * fac * fac * fac);
1142                 }
1143                 else {
1144                         return (1.0f - fac) * cur_w + fac * next_w;
1145                 }
1146         }
1147 }
1148
1149 MaskSplinePointUW *BKE_mask_point_sort_uw(MaskSplinePoint *point, MaskSplinePointUW *uw)
1150 {
1151         if (point->tot_uw > 1) {
1152                 int idx = uw - point->uw;
1153
1154                 if (idx > 0 && point->uw[idx - 1].u > uw->u) {
1155                         while (idx > 0 && point->uw[idx - 1].u > point->uw[idx].u) {
1156                                 SWAP(MaskSplinePointUW, point->uw[idx - 1], point->uw[idx]);
1157                                 idx--;
1158                         }
1159                 }
1160
1161                 if (idx < point->tot_uw - 1 && point->uw[idx + 1].u < uw->u) {
1162                         while (idx < point->tot_uw - 1 && point->uw[idx + 1].u < point->uw[idx].u) {
1163                                 SWAP(MaskSplinePointUW, point->uw[idx + 1], point->uw[idx]);
1164                                 idx++;
1165                         }
1166                 }
1167
1168                 return &point->uw[idx];
1169         }
1170
1171         return uw;
1172 }
1173
1174 void BKE_mask_point_add_uw(MaskSplinePoint *point, float u, float w)
1175 {
1176         if (!point->uw)
1177                 point->uw = MEM_callocN(sizeof(*point->uw), "mask point uw");
1178         else
1179                 point->uw = MEM_reallocN(point->uw, (point->tot_uw + 1) * sizeof(*point->uw));
1180
1181         point->uw[point->tot_uw].u = u;
1182         point->uw[point->tot_uw].w = w;
1183
1184         point->tot_uw++;
1185
1186         BKE_mask_point_sort_uw(point, &point->uw[point->tot_uw - 1]);
1187 }
1188
1189 void BKE_mask_point_select_set(MaskSplinePoint *point, const short do_select)
1190 {
1191         int i;
1192
1193         if (do_select) {
1194                 MASKPOINT_SEL_ALL(point);
1195         }
1196         else {
1197                 MASKPOINT_DESEL_ALL(point);
1198         }
1199
1200         for (i = 0; i < point->tot_uw; i++) {
1201                 if (do_select) {
1202                         point->uw[i].flag |= SELECT;
1203                 }
1204                 else {
1205                         point->uw[i].flag &= ~SELECT;
1206                 }
1207         }
1208 }
1209
1210 void BKE_mask_point_select_set_handle(MaskSplinePoint *point, const short do_select)
1211 {
1212         if (do_select) {
1213                 MASKPOINT_SEL_HANDLE(point);
1214         }
1215         else {
1216                 MASKPOINT_DESEL_HANDLE(point);
1217         }
1218 }
1219
1220 /* only mask block itself */
1221 static Mask *mask_alloc(const char *name)
1222 {
1223         Mask *mask;
1224
1225         mask = BKE_libblock_alloc(&G.main->mask, ID_MSK, name);
1226
1227         return mask;
1228 }
1229
1230 Mask *BKE_mask_new(const char *name)
1231 {
1232         Mask *mask;
1233         char mask_name[MAX_ID_NAME - 2];
1234
1235         if (name && name[0])
1236                 BLI_strncpy(mask_name, name, sizeof(mask_name));
1237         else
1238                 strcpy(mask_name, "Mask");
1239
1240         mask = mask_alloc(mask_name);
1241
1242         /* arbitrary defaults */
1243         mask->sfra = 1;
1244         mask->efra = 100;
1245
1246         return mask;
1247 }
1248
1249 void BKE_mask_point_free(MaskSplinePoint *point)
1250 {
1251         if (point->uw)
1252                 MEM_freeN(point->uw);
1253 }
1254
1255 void BKE_mask_spline_free(MaskSpline *spline)
1256 {
1257         int i = 0;
1258
1259         for (i = 0; i < spline->tot_point; i++) {
1260                 MaskSplinePoint *point;
1261                 point = &spline->points[i];
1262                 BKE_mask_point_free(point);
1263
1264                 if (spline->points_deform) {
1265                         point = &spline->points_deform[i];
1266                         BKE_mask_point_free(point);
1267                 }
1268         }
1269
1270         MEM_freeN(spline->points);
1271
1272         if (spline->points_deform) {
1273                 MEM_freeN(spline->points_deform);
1274         }
1275
1276         MEM_freeN(spline);
1277 }
1278
1279 static MaskSplinePoint *mask_spline_points_copy(MaskSplinePoint *points, int tot_point)
1280 {
1281         MaskSplinePoint *npoints;
1282         int i;
1283
1284         npoints = MEM_dupallocN(points);
1285
1286         for (i = 0; i < tot_point; i++) {
1287                 MaskSplinePoint *point = &npoints[i];
1288
1289                 if (point->uw)
1290                         point->uw = MEM_dupallocN(point->uw);
1291         }
1292
1293         return npoints;
1294 }
1295
1296 MaskSpline *BKE_mask_spline_copy(MaskSpline *spline)
1297 {
1298         MaskSpline *nspline = MEM_callocN(sizeof(MaskSpline), "new spline");
1299
1300         *nspline = *spline;
1301
1302         nspline->points_deform = NULL;
1303         nspline->points = mask_spline_points_copy(spline->points, spline->tot_point);
1304
1305         if (spline->points_deform) {
1306                 nspline->points_deform = mask_spline_points_copy(spline->points_deform, spline->tot_point);
1307         }
1308
1309         return nspline;
1310 }
1311
1312 /* note: does NOT add to the list */
1313 MaskLayerShape *BKE_mask_layer_shape_alloc(MaskLayer *masklay, const int frame)
1314 {
1315         MaskLayerShape *masklay_shape;
1316         int tot_vert = BKE_mask_layer_shape_totvert(masklay);
1317
1318         masklay_shape = MEM_mallocN(sizeof(MaskLayerShape), __func__);
1319         masklay_shape->frame = frame;
1320         masklay_shape->tot_vert = tot_vert;
1321         masklay_shape->data = MEM_mallocN(tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__);
1322
1323         return masklay_shape;
1324 }
1325
1326 void BKE_mask_layer_shape_free(MaskLayerShape *masklay_shape)
1327 {
1328         MEM_freeN(masklay_shape->data);
1329
1330         MEM_freeN(masklay_shape);
1331 }
1332
1333 /** \brief Free all animation keys for a mask layer
1334  */
1335 void BKE_mask_layer_free_shapes(MaskLayer *masklay)
1336 {
1337         MaskLayerShape *masklay_shape;
1338
1339         /* free animation data */
1340         masklay_shape = masklay->splines_shapes.first;
1341         while (masklay_shape) {
1342                 MaskLayerShape *next_masklay_shape = masklay_shape->next;
1343
1344                 BLI_remlink(&masklay->splines_shapes, masklay_shape);
1345                 BKE_mask_layer_shape_free(masklay_shape);
1346
1347                 masklay_shape = next_masklay_shape;
1348         }
1349 }
1350
1351 void BKE_mask_layer_free(MaskLayer *masklay)
1352 {
1353         MaskSpline *spline;
1354
1355         /* free splines */
1356         spline = masklay->splines.first;
1357         while (spline) {
1358                 MaskSpline *next_spline = spline->next;
1359
1360                 BLI_remlink(&masklay->splines, spline);
1361                 BKE_mask_spline_free(spline);
1362
1363                 spline = next_spline;
1364         }
1365
1366         /* free animation data */
1367         BKE_mask_layer_free_shapes(masklay);
1368
1369         MEM_freeN(masklay);
1370 }
1371
1372
1373 void BKE_mask_layer_free_list(ListBase *masklayers)
1374 {
1375         MaskLayer *masklay = masklayers->first;
1376
1377         while (masklay) {
1378                 MaskLayer *masklay_next = masklay->next;
1379
1380                 BLI_remlink(masklayers, masklay);
1381                 BKE_mask_layer_free(masklay);
1382
1383                 masklay = masklay_next;
1384         }
1385
1386 }
1387
1388 #ifdef USE_MANGO_MASK_CACHE_HACK
1389 void BKE_mask_raster_cache_free(Mask *mask)
1390 {
1391         MaskRasterCache *cache = mask->raster_cache;
1392
1393         if (cache) {
1394                 MaskLayer *layer;
1395
1396                 layer = cache->layers.first;
1397                 while (layer) {
1398                         MaskLayer *layer_next = layer->next;
1399
1400                         BKE_mask_layer_free(layer);
1401                         layer = layer_next;
1402                 }
1403
1404                 MEM_freeN(cache->buffer);
1405                 MEM_freeN(cache);
1406
1407                 mask->raster_cache = NULL;
1408         }
1409 }
1410 #endif
1411
1412 void BKE_mask_free(Mask *mask)
1413 {
1414         BKE_mask_layer_free_list(&mask->masklayers);
1415
1416 #ifdef USE_MANGO_MASK_CACHE_HACK
1417         if (mask->raster_cache) {
1418                 BKE_mask_raster_cache_free(mask);
1419
1420                 mask->raster_cache = NULL;
1421         }
1422 #endif
1423 }
1424
1425 void BKE_mask_unlink(Main *bmain, Mask *mask)
1426 {
1427         bScreen *scr;
1428         ScrArea *area;
1429         SpaceLink *sl;
1430
1431         for (scr = bmain->screen.first; scr; scr = scr->id.next) {
1432                 for (area = scr->areabase.first; area; area = area->next) {
1433                         for (sl = area->spacedata.first; sl; sl = sl->next) {
1434                                 if (sl->spacetype == SPACE_CLIP) {
1435                                         SpaceClip *sc = (SpaceClip *) sl;
1436
1437                                         if (sc->mask == mask)
1438                                                 sc->mask = NULL;
1439                                 }
1440                         }
1441                 }
1442         }
1443
1444         mask->id.us = 0;
1445 }
1446
1447 void BKE_mask_coord_from_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2])
1448 {
1449         int width, height;
1450
1451         /* scaling for the clip */
1452         BKE_movieclip_get_size(clip, user, &width, &height);
1453
1454         if (width == height) {
1455                 r_co[0] = co[0];
1456                 r_co[1] = co[1];
1457         }
1458         else if (width < height) {
1459                 r_co[0] = ((co[0] - 0.5f) * ((float)width / (float)height)) + 0.5f;
1460                 r_co[1] = co[1];
1461         }
1462         else { /* (width > height) */
1463                 r_co[0] = co[0];
1464                 r_co[1] = ((co[1] - 0.5f) * ((float)height / (float)width)) + 0.5f;
1465         }
1466 }
1467
1468 /* as above but divide */
1469 void BKE_mask_coord_to_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2])
1470 {
1471         int width, height;
1472
1473         /* scaling for the clip */
1474         BKE_movieclip_get_size(clip, user, &width, &height);
1475
1476         if (width == height) {
1477                 r_co[0] = co[0];
1478                 r_co[1] = co[1];
1479         }
1480         else if (width < height) {
1481                 r_co[0] = ((co[0] - 0.5f) / ((float)width / (float)height)) + 0.5f;
1482                 r_co[1] = co[1];
1483         }
1484         else { /* (width > height) */
1485                 r_co[0] = co[0];
1486                 r_co[1] = ((co[1] - 0.5f) / ((float)height / (float)width)) + 0.5f;
1487         }
1488 }
1489
1490 static int BKE_mask_evaluate_parent(MaskParent *parent, float ctime, float r_co[2])
1491 {
1492         if (!parent)
1493                 return FALSE;
1494
1495         if (parent->id_type == ID_MC) {
1496                 if (parent->id) {
1497                         MovieClip *clip = (MovieClip *) parent->id;
1498                         MovieTracking *tracking = (MovieTracking *) &clip->tracking;
1499                         MovieTrackingObject *ob = BKE_tracking_object_get_named(tracking, parent->parent);
1500
1501                         if (ob) {
1502                                 MovieTrackingTrack *track = BKE_tracking_track_get_named(tracking, ob, parent->sub_parent);
1503                                 float clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, ctime);
1504
1505                                 MovieClipUser user = {0};
1506                                 user.framenr = ctime;
1507
1508                                 if (track) {
1509                                         MovieTrackingMarker *marker = BKE_tracking_marker_get(track, clip_framenr);
1510                                         float marker_pos_ofs[2];
1511                                         add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset);
1512                                         BKE_mask_coord_from_movieclip(clip, &user, r_co, marker_pos_ofs);
1513
1514                                         return TRUE;
1515                                 }
1516                         }
1517                 }
1518         }
1519
1520         return FALSE;
1521 }
1522
1523 int BKE_mask_evaluate_parent_delta(MaskParent *parent, float ctime, float r_delta[2])
1524 {
1525         float parent_co[2];
1526
1527         if (BKE_mask_evaluate_parent(parent, ctime, parent_co)) {
1528                 sub_v2_v2v2(r_delta, parent_co, parent->parent_orig);
1529                 return TRUE;
1530         }
1531         else {
1532                 return FALSE;
1533         }
1534 }
1535
1536 static void mask_calc_point_handle(MaskSplinePoint *point, MaskSplinePoint *point_prev, MaskSplinePoint *point_next)
1537 {
1538         BezTriple *bezt = &point->bezt;
1539         BezTriple *bezt_prev = NULL, *bezt_next = NULL;
1540         //int handle_type = bezt->h1;
1541
1542         if (point_prev)
1543                 bezt_prev = &point_prev->bezt;
1544
1545         if (point_next)
1546                 bezt_next = &point_next->bezt;
1547
1548 #if 1
1549         if (bezt_prev || bezt_next) {
1550                 BKE_nurb_handle_calc(bezt, bezt_prev, bezt_next, 0);
1551         }
1552 #else
1553         if (handle_type == HD_VECT) {
1554                 BKE_nurb_handle_calc(bezt, bezt_prev, bezt_next, 0);
1555         }
1556         else if (handle_type == HD_AUTO) {
1557                 BKE_nurb_handle_calc(bezt, bezt_prev, bezt_next, 0);
1558         }
1559         else if (handle_type == HD_ALIGN) {
1560                 float v1[3], v2[3];
1561                 float vec[3], h[3];
1562
1563                 sub_v3_v3v3(v1, bezt->vec[0], bezt->vec[1]);
1564                 sub_v3_v3v3(v2, bezt->vec[2], bezt->vec[1]);
1565                 add_v3_v3v3(vec, v1, v2);
1566
1567                 if (len_v3(vec) > 1e-3) {
1568                         h[0] = vec[1];
1569                         h[1] = -vec[0];
1570                         h[2] = 0.0f;
1571                 }
1572                 else {
1573                         copy_v3_v3(h, v1);
1574                 }
1575
1576                 add_v3_v3v3(bezt->vec[0], bezt->vec[1], h);
1577                 sub_v3_v3v3(bezt->vec[2], bezt->vec[1], h);
1578         }
1579 #endif
1580 }
1581
1582 void BKE_mask_get_handle_point_adjacent(MaskSpline *spline, MaskSplinePoint *point,
1583                                         MaskSplinePoint **r_point_prev, MaskSplinePoint **r_point_next)
1584 {
1585         /* TODO, could avoid calling this at such low level */
1586         MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
1587
1588         *r_point_prev = mask_spline_point_prev(spline, points_array, point);
1589         *r_point_next = mask_spline_point_next(spline, points_array, point);
1590 }
1591
1592 /* calculates the tanget of a point by its previous and next
1593  * (ignoring handles - as if its a poly line) */
1594 void BKE_mask_calc_tangent_polyline(MaskSpline *spline, MaskSplinePoint *point, float t[2])
1595 {
1596         float tvec_a[2], tvec_b[2];
1597
1598         MaskSplinePoint *point_prev, *point_next;
1599
1600         BKE_mask_get_handle_point_adjacent(spline, point,
1601                                            &point_prev, &point_next);
1602
1603         if (point_prev) {
1604                 sub_v2_v2v2(tvec_a, point->bezt.vec[1], point_prev->bezt.vec[1]);
1605                 normalize_v2(tvec_a);
1606         }
1607         else {
1608                 zero_v2(tvec_a);
1609         }
1610
1611         if (point_next) {
1612                 sub_v2_v2v2(tvec_b, point_next->bezt.vec[1], point->bezt.vec[1]);
1613                 normalize_v2(tvec_b);
1614         }
1615         else {
1616                 zero_v2(tvec_b);
1617         }
1618
1619         add_v2_v2v2(t, tvec_a, tvec_b);
1620         normalize_v2(t);
1621 }
1622
1623 void BKE_mask_calc_handle_point(MaskSpline *spline, MaskSplinePoint *point)
1624 {
1625         MaskSplinePoint *point_prev, *point_next;
1626
1627         BKE_mask_get_handle_point_adjacent(spline, point,
1628                                            &point_prev, &point_next);
1629
1630         mask_calc_point_handle(point, point_prev, point_next);
1631 }
1632
1633 static void enforce_dist_v2_v2fl(float v1[2], const float v2[2], const float dist)
1634 {
1635         if (!equals_v2v2(v2, v1)) {
1636                 float nor[2];
1637
1638                 sub_v2_v2v2(nor, v1, v2);
1639                 normalize_v2(nor);
1640                 madd_v2_v2v2fl(v1, v2, nor, dist);
1641         }
1642 }
1643
1644 void BKE_mask_calc_handle_adjacent_interp(MaskSpline *spline, MaskSplinePoint *point, const float u)
1645 {
1646         /* TODO! - make this interpolate between siblings - not always midpoint! */
1647         int length_tot = 0;
1648         float length_average = 0.0f;
1649         float weight_average = 0.0f;
1650
1651
1652         MaskSplinePoint *point_prev, *point_next;
1653
1654         BLI_assert(u >= 0.0f && u <= 1.0f);
1655
1656         BKE_mask_get_handle_point_adjacent(spline, point,
1657                                            &point_prev, &point_next);
1658
1659         if (point_prev && point_next) {
1660                 length_average = ((len_v2v2(point_prev->bezt.vec[0], point_prev->bezt.vec[1]) * (1.0f - u)) +
1661                                   (len_v2v2(point_next->bezt.vec[2], point_next->bezt.vec[1]) * u));
1662
1663                 weight_average = (point_prev->bezt.weight * (1.0f - u) +
1664                                   point_next->bezt.weight * u);
1665                 length_tot = 1;
1666         }
1667         else {
1668                 if (point_prev) {
1669                         length_average += len_v2v2(point_prev->bezt.vec[0], point_prev->bezt.vec[1]);
1670                         weight_average += point_prev->bezt.weight;
1671                         length_tot++;
1672                 }
1673
1674                 if (point_next) {
1675                         length_average += len_v2v2(point_next->bezt.vec[2], point_next->bezt.vec[1]);
1676                         weight_average += point_next->bezt.weight;
1677                         length_tot++;
1678                 }
1679         }
1680
1681         if (length_tot) {
1682                 length_average /= (float)length_tot;
1683                 weight_average /= (float)length_tot;
1684
1685                 enforce_dist_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average);
1686                 enforce_dist_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average);
1687                 point->bezt.weight = weight_average;
1688         }
1689 }
1690
1691
1692 /**
1693  * \brief Resets auto handles even for non-auto bezier points
1694  *
1695  * Useful for giving sane defaults.
1696  */
1697 void BKE_mask_calc_handle_point_auto(MaskSpline *spline, MaskSplinePoint *point,
1698                                      const short do_recalc_length)
1699 {
1700         MaskSplinePoint *point_prev, *point_next;
1701         const char h_back[2] = {point->bezt.h1, point->bezt.h2};
1702         const float length_average = (do_recalc_length) ? 0.0f /* dummy value */ :
1703                                      (len_v3v3(point->bezt.vec[0], point->bezt.vec[1]) +
1704                                       len_v3v3(point->bezt.vec[1], point->bezt.vec[2])) / 2.0f;
1705
1706         BKE_mask_get_handle_point_adjacent(spline, point,
1707                                            &point_prev, &point_next);
1708
1709         point->bezt.h1 = HD_AUTO;
1710         point->bezt.h2 = HD_AUTO;
1711         mask_calc_point_handle(point, point_prev, point_next);
1712
1713         point->bezt.h1 = h_back[0];
1714         point->bezt.h2 = h_back[1];
1715
1716         /* preserve length by applying it back */
1717         if (do_recalc_length == FALSE) {
1718                 enforce_dist_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average);
1719                 enforce_dist_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average);
1720         }
1721 }
1722
1723 void BKE_mask_layer_calc_handles(MaskLayer *masklay)
1724 {
1725         MaskSpline *spline;
1726         for (spline = masklay->splines.first; spline; spline = spline->next) {
1727                 int i;
1728                 for (i = 0; i < spline->tot_point; i++) {
1729                         BKE_mask_calc_handle_point(spline, &spline->points[i]);
1730                 }
1731         }
1732 }
1733
1734 void BKE_mask_layer_calc_handles_deform(MaskLayer *masklay)
1735 {
1736         MaskSpline *spline;
1737         for (spline = masklay->splines.first; spline; spline = spline->next) {
1738                 int i;
1739                 for (i = 0; i < spline->tot_point; i++) {
1740                         BKE_mask_calc_handle_point(spline, &spline->points_deform[i]);
1741                 }
1742         }
1743 }
1744
1745 void BKE_mask_calc_handles(Mask *mask)
1746 {
1747         MaskLayer *masklay;
1748         for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
1749                 BKE_mask_layer_calc_handles(masklay);
1750         }
1751 }
1752
1753 void BKE_mask_update_deform(Mask *mask)
1754 {
1755         MaskLayer *masklay;
1756
1757         for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
1758                 MaskSpline *spline;
1759
1760                 for (spline = masklay->splines.first; spline; spline = spline->next) {
1761                         int i;
1762
1763                         for (i = 0; i < spline->tot_point; i++) {
1764                                 const int i_prev = (i - 1) % spline->tot_point;
1765                                 const int i_next = (i + 1) % spline->tot_point;
1766
1767                                 BezTriple *bezt_prev = &spline->points[i_prev].bezt;
1768                                 BezTriple *bezt      = &spline->points[i].bezt;
1769                                 BezTriple *bezt_next = &spline->points[i_next].bezt;
1770
1771                                 BezTriple *bezt_def_prev = &spline->points_deform[i_prev].bezt;
1772                                 BezTriple *bezt_def      = &spline->points_deform[i].bezt;
1773                                 BezTriple *bezt_def_next = &spline->points_deform[i_next].bezt;
1774
1775                                 float w_src[4];
1776                                 int j;
1777
1778                                 for (j = 0; j <= 2; j += 2) { /* (0, 2) */
1779                                         printf("--- %d %d, %d, %d\n", i, j, i_prev, i_next);
1780                                         barycentric_weights_v2(bezt_prev->vec[1], bezt->vec[1], bezt_next->vec[1],
1781                                                                bezt->vec[j], w_src);
1782                                         interp_v3_v3v3v3(bezt_def->vec[j],
1783                                                          bezt_def_prev->vec[1], bezt_def->vec[1], bezt_def_next->vec[1], w_src);
1784                                 }
1785                         }
1786                 }
1787         }
1788 }
1789
1790 void BKE_mask_spline_ensure_deform(MaskSpline *spline)
1791 {
1792         int allocated_points = (MEM_allocN_len(spline->points_deform) / sizeof(*spline->points_deform));
1793         // printf("SPLINE ALLOC %p %d\n", spline->points_deform, allocated_points);
1794
1795         if (spline->points_deform == NULL || allocated_points != spline->tot_point) {
1796                 // printf("alloc new deform spline\n");
1797
1798                 if (spline->points_deform) {
1799                         int i;
1800
1801                         for (i = 0; i < allocated_points; i++) {
1802                                 MaskSplinePoint *point = &spline->points_deform[i];
1803                                 BKE_mask_point_free(point);
1804                         }
1805
1806                         MEM_freeN(spline->points_deform);
1807                 }
1808
1809                 spline->points_deform = MEM_callocN(sizeof(*spline->points_deform) * spline->tot_point, __func__);
1810         }
1811         else {
1812                 // printf("alloc spline done\n");
1813         }
1814 }
1815
1816 void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const int do_newframe)
1817 {
1818         /* animation if available */
1819         if (do_newframe) {
1820                 MaskLayerShape *masklay_shape_a;
1821                 MaskLayerShape *masklay_shape_b;
1822                 int found;
1823
1824                 if ((found = BKE_mask_layer_shape_find_frame_range(masklay, ctime,
1825                                                                    &masklay_shape_a, &masklay_shape_b)))
1826                 {
1827                         if (found == 1) {
1828 #if 0
1829                                 printf("%s: exact %d %d (%d)\n", __func__, (int)ctime, BLI_countlist(&masklay->splines_shapes),
1830                                        masklay_shape_a->frame);
1831 #endif
1832
1833                                 BKE_mask_layer_shape_to_mask(masklay, masklay_shape_a);
1834                         }
1835                         else if (found == 2) {
1836                                 float w = masklay_shape_b->frame - masklay_shape_a->frame;
1837 #if 0
1838                                 printf("%s: tween %d %d (%d %d)\n", __func__, (int)ctime, BLI_countlist(&masklay->splines_shapes),
1839                                        masklay_shape_a->frame, masklay_shape_b->frame);
1840 #endif
1841                                 BKE_mask_layer_shape_to_mask_interp(masklay, masklay_shape_a, masklay_shape_b,
1842                                                                     (ctime - masklay_shape_a->frame) / w);
1843                         }
1844                         else {
1845                                 /* always fail, should never happen */
1846                                 BLI_assert(found == 2);
1847                         }
1848                 }
1849         }
1850         /* animation done... */
1851
1852         BKE_mask_layer_calc_handles(masklay);
1853
1854         /* update deform */
1855         {
1856                 MaskSpline *spline;
1857
1858                 for (spline = masklay->splines.first; spline; spline = spline->next) {
1859                         int i;
1860                         int has_auto = FALSE;
1861
1862                         BKE_mask_spline_ensure_deform(spline);
1863
1864                         for (i = 0; i < spline->tot_point; i++) {
1865                                 MaskSplinePoint *point = &spline->points[i];
1866                                 MaskSplinePoint *point_deform = &spline->points_deform[i];
1867                                 float delta[2];
1868
1869                                 BKE_mask_point_free(point_deform);
1870
1871                                 *point_deform = *point;
1872                                 point_deform->uw = point->uw ? MEM_dupallocN(point->uw) : NULL;
1873
1874                                 if (BKE_mask_evaluate_parent_delta(&point->parent, ctime, delta)) {
1875                                         add_v2_v2(point_deform->bezt.vec[0], delta);
1876                                         add_v2_v2(point_deform->bezt.vec[1], delta);
1877                                         add_v2_v2(point_deform->bezt.vec[2], delta);
1878                                 }
1879
1880                                 if (point->bezt.h1 == HD_AUTO) {
1881                                         has_auto = TRUE;
1882                                 }
1883                         }
1884
1885                         /* if the spline has auto handles, these need to be recalculated after deformation */
1886                         if (has_auto) {
1887                                 for (i = 0; i < spline->tot_point; i++) {
1888                                         MaskSplinePoint *point_deform = &spline->points_deform[i];
1889                                         if (point_deform->bezt.h1 == HD_AUTO) {
1890                                                 BKE_mask_calc_handle_point(spline, point_deform);
1891                                         }
1892                                 }
1893                         }
1894                         /* end extra calc handles loop */
1895                 }
1896         }
1897 }
1898
1899 void BKE_mask_evaluate(Mask *mask, const float ctime, const int do_newframe)
1900 {
1901         MaskLayer *masklay;
1902
1903         for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
1904                 BKE_mask_layer_evaluate(masklay, ctime, do_newframe);
1905         }
1906 }
1907
1908 /* the purpose of this function is to ensure spline->points_deform is never out of date.
1909  * for now re-evaluate all. eventually this might work differently */
1910 void BKE_mask_update_display(Mask *mask, float ctime)
1911 {
1912 #if 0
1913         MaskLayer *masklay;
1914
1915         for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
1916                 MaskSpline *spline;
1917
1918                 for (spline = masklay->splines.first; spline; spline = spline->next) {
1919                         if (spline->points_deform) {
1920                                 int i = 0;
1921
1922                                 for (i = 0; i < spline->tot_point; i++) {
1923                                         MaskSplinePoint *point;
1924
1925                                         if (spline->points_deform) {
1926                                                 point = &spline->points_deform[i];
1927                                                 BKE_mask_point_free(point);
1928                                         }
1929                                 }
1930                                 if (spline->points_deform) {
1931                                         MEM_freeN(spline->points_deform);
1932                                 }
1933
1934                                 spline->points_deform = NULL;
1935                         }
1936                 }
1937         }
1938 #endif
1939
1940         BKE_mask_evaluate(mask, ctime, FALSE);
1941 }
1942
1943 void BKE_mask_evaluate_all_masks(Main *bmain, float ctime, const int do_newframe)
1944 {
1945         Mask *mask;
1946
1947         for (mask = bmain->mask.first; mask; mask = mask->id.next) {
1948                 BKE_mask_evaluate(mask, ctime, do_newframe);
1949         }
1950 }
1951
1952 void BKE_mask_update_scene(Main *bmain, Scene *scene, const int do_newframe)
1953 {
1954         Mask *mask;
1955
1956         for (mask = bmain->mask.first; mask; mask = mask->id.next) {
1957                 if (mask->id.flag & LIB_ID_RECALC) {
1958                         BKE_mask_evaluate_all_masks(bmain, CFRA, do_newframe);
1959                 }
1960         }
1961 }
1962
1963 void BKE_mask_parent_init(MaskParent *parent)
1964 {
1965         parent->id_type = ID_MC;
1966 }
1967
1968
1969 /* *** own animation/shapekey implimentation ***
1970  * BKE_mask_layer_shape_XXX */
1971
1972 int BKE_mask_layer_shape_totvert(MaskLayer *masklay)
1973 {
1974         int tot = 0;
1975         MaskSpline *spline;
1976
1977         for (spline = masklay->splines.first; spline; spline = spline->next) {
1978                 tot += spline->tot_point;
1979         }
1980
1981         return tot;
1982 }
1983
1984 static void mask_layer_shape_from_mask_point(BezTriple *bezt, float fp[MASK_OBJECT_SHAPE_ELEM_SIZE])
1985 {
1986         copy_v2_v2(&fp[0], bezt->vec[0]);
1987         copy_v2_v2(&fp[2], bezt->vec[1]);
1988         copy_v2_v2(&fp[4], bezt->vec[2]);
1989         fp[6] = bezt->weight;
1990         fp[7] = bezt->radius;
1991 }
1992
1993 static void mask_layer_shape_to_mask_point(BezTriple *bezt, float fp[MASK_OBJECT_SHAPE_ELEM_SIZE])
1994 {
1995         copy_v2_v2(bezt->vec[0], &fp[0]);
1996         copy_v2_v2(bezt->vec[1], &fp[2]);
1997         copy_v2_v2(bezt->vec[2], &fp[4]);
1998         bezt->weight = fp[6];
1999         bezt->radius = fp[7];
2000 }
2001
2002 /* these functions match. copy is swapped */
2003 void BKE_mask_layer_shape_from_mask(MaskLayer *masklay, MaskLayerShape *masklay_shape)
2004 {
2005         int tot = BKE_mask_layer_shape_totvert(masklay);
2006
2007         if (masklay_shape->tot_vert == tot) {
2008                 float *fp = masklay_shape->data;
2009
2010                 MaskSpline *spline;
2011                 for (spline = masklay->splines.first; spline; spline = spline->next) {
2012                         int i;
2013                         for (i = 0; i < spline->tot_point; i++) {
2014                                 mask_layer_shape_from_mask_point(&spline->points[i].bezt, fp);
2015                                 fp += MASK_OBJECT_SHAPE_ELEM_SIZE;
2016                         }
2017                 }
2018         }
2019         else {
2020                 printf("%s: vert mismatch %d != %d (frame %d)\n",
2021                        __func__, masklay_shape->tot_vert, tot, masklay_shape->frame);
2022         }
2023 }
2024
2025 void BKE_mask_layer_shape_to_mask(MaskLayer *masklay, MaskLayerShape *masklay_shape)
2026 {
2027         int tot = BKE_mask_layer_shape_totvert(masklay);
2028
2029         if (masklay_shape->tot_vert == tot) {
2030                 float *fp = masklay_shape->data;
2031
2032                 MaskSpline *spline;
2033                 for (spline = masklay->splines.first; spline; spline = spline->next) {
2034                         int i;
2035                         for (i = 0; i < spline->tot_point; i++) {
2036                                 mask_layer_shape_to_mask_point(&spline->points[i].bezt, fp);
2037                                 fp += MASK_OBJECT_SHAPE_ELEM_SIZE;
2038                         }
2039                 }
2040         }
2041         else {
2042                 printf("%s: vert mismatch %d != %d (frame %d)\n",
2043                        __func__, masklay_shape->tot_vert, tot, masklay_shape->frame);
2044         }
2045 }
2046
2047 BLI_INLINE void interp_v2_v2v2_flfl(float target[2], const float a[2], const float b[2],
2048                                     const float t, const float s)
2049 {
2050         target[0] = s * a[0] + t * b[0];
2051         target[1] = s * a[1] + t * b[1];
2052 }
2053
2054 /* linear interpolation only */
2055 void BKE_mask_layer_shape_to_mask_interp(MaskLayer *masklay,
2056                                          MaskLayerShape *masklay_shape_a,
2057                                          MaskLayerShape *masklay_shape_b,
2058                                          const float fac)
2059 {
2060         int tot = BKE_mask_layer_shape_totvert(masklay);
2061         if (masklay_shape_a->tot_vert == tot && masklay_shape_b->tot_vert == tot) {
2062                 float *fp_a = masklay_shape_a->data;
2063                 float *fp_b = masklay_shape_b->data;
2064                 const float ifac = 1.0f - fac;
2065
2066                 MaskSpline *spline;
2067                 for (spline = masklay->splines.first; spline; spline = spline->next) {
2068                         int i;
2069                         for (i = 0; i < spline->tot_point; i++) {
2070                                 BezTriple *bezt = &spline->points[i].bezt;
2071                                 /* *** BKE_mask_layer_shape_from_mask - swapped *** */
2072                                 interp_v2_v2v2_flfl(bezt->vec[0], fp_a, fp_b, fac, ifac); fp_a += 2; fp_b += 2;
2073                                 interp_v2_v2v2_flfl(bezt->vec[1], fp_a, fp_b, fac, ifac); fp_a += 2; fp_b += 2;
2074                                 interp_v2_v2v2_flfl(bezt->vec[2], fp_a, fp_b, fac, ifac); fp_a += 2; fp_b += 2;
2075                                 bezt->weight = (fp_a[0] * ifac) + (fp_b[0] * fac);
2076                                 bezt->radius = (fp_a[1] * ifac) + (fp_b[1] * fac); fp_a += 2; fp_b += 2;
2077                         }
2078                 }
2079         }
2080         else {
2081                 printf("%s: vert mismatch %d != %d != %d (frame %d - %d)\n",
2082                        __func__, masklay_shape_a->tot_vert, masklay_shape_b->tot_vert, tot,
2083                        masklay_shape_a->frame, masklay_shape_b->frame);
2084         }
2085 }
2086
2087 MaskLayerShape *BKE_mask_layer_shape_find_frame(MaskLayer *masklay, const int frame)
2088 {
2089         MaskLayerShape *masklay_shape;
2090
2091         for (masklay_shape = masklay->splines_shapes.first;
2092              masklay_shape;
2093              masklay_shape = masklay_shape->next)
2094         {
2095                 if (frame == masklay_shape->frame) {
2096                         return masklay_shape;
2097                 }
2098                 else if (frame < masklay_shape->frame) {
2099                         break;
2100                 }
2101         }
2102
2103         return NULL;
2104 }
2105
2106 /* when returning 2 - the frame isnt found but before/after frames are */
2107 int BKE_mask_layer_shape_find_frame_range(MaskLayer *masklay, const float frame,
2108                                           MaskLayerShape **r_masklay_shape_a,
2109                                           MaskLayerShape **r_masklay_shape_b)
2110 {
2111         MaskLayerShape *masklay_shape;
2112
2113         for (masklay_shape = masklay->splines_shapes.first;
2114              masklay_shape;
2115              masklay_shape = masklay_shape->next)
2116         {
2117                 if (frame == masklay_shape->frame) {
2118                         *r_masklay_shape_a = masklay_shape;
2119                         *r_masklay_shape_b = NULL;
2120                         return 1;
2121                 }
2122                 else if (frame < masklay_shape->frame) {
2123                         if (masklay_shape->prev) {
2124                                 *r_masklay_shape_a = masklay_shape->prev;
2125                                 *r_masklay_shape_b = masklay_shape;
2126                                 return 2;
2127                         }
2128                         else {
2129                                 *r_masklay_shape_a = masklay_shape;
2130                                 *r_masklay_shape_b = NULL;
2131                                 return 1;
2132                         }
2133                 }
2134         }
2135
2136         if ((masklay_shape = masklay->splines_shapes.last)) {
2137                 *r_masklay_shape_a = masklay_shape;
2138                 *r_masklay_shape_b = NULL;
2139                 return 1;
2140         }
2141         else {
2142                 *r_masklay_shape_a = NULL;
2143                 *r_masklay_shape_b = NULL;
2144
2145                 return 0;
2146         }
2147 }
2148
2149 MaskLayerShape *BKE_mask_layer_shape_varify_frame(MaskLayer *masklay, const int frame)
2150 {
2151         MaskLayerShape *masklay_shape;
2152
2153         masklay_shape = BKE_mask_layer_shape_find_frame(masklay, frame);
2154
2155         if (masklay_shape == NULL) {
2156                 masklay_shape = BKE_mask_layer_shape_alloc(masklay, frame);
2157                 BLI_addtail(&masklay->splines_shapes, masklay_shape);
2158                 BKE_mask_layer_shape_sort(masklay);
2159         }
2160
2161 #if 0
2162         {
2163                 MaskLayerShape *masklay_shape;
2164                 int i = 0;
2165                 for (masklay_shape = masklay->splines_shapes.first;
2166                      masklay_shape;
2167                      masklay_shape = masklay_shape->next)
2168                 {
2169                         printf("mask %d, %d\n", i++, masklay_shape->frame);
2170                 }
2171         }
2172 #endif
2173
2174         return masklay_shape;
2175 }
2176
2177 MaskLayerShape *BKE_mask_layer_shape_duplicate(MaskLayerShape *masklay_shape)
2178 {
2179         MaskLayerShape *masklay_shape_copy;
2180
2181         masklay_shape_copy = MEM_dupallocN(masklay_shape);
2182
2183         if (LIKELY(masklay_shape_copy->data)) {
2184                 masklay_shape_copy->data = MEM_dupallocN(masklay_shape_copy->data);
2185         }
2186
2187         return masklay_shape_copy;
2188 }
2189
2190 void BKE_mask_layer_shape_unlink(MaskLayer *masklay, MaskLayerShape *masklay_shape)
2191 {
2192         BLI_remlink(&masklay->splines_shapes, masklay_shape);
2193
2194         BKE_mask_layer_shape_free(masklay_shape);
2195 }
2196
2197 static int mask_layer_shape_sort_cb(void *masklay_shape_a_ptr, void *masklay_shape_b_ptr)
2198 {
2199         MaskLayerShape *masklay_shape_a = (MaskLayerShape *)masklay_shape_a_ptr;
2200         MaskLayerShape *masklay_shape_b = (MaskLayerShape *)masklay_shape_b_ptr;
2201
2202         if      (masklay_shape_a->frame < masklay_shape_b->frame)  return -1;
2203         else if (masklay_shape_a->frame > masklay_shape_b->frame)  return  1;
2204         else                                                       return  0;
2205 }
2206
2207 void BKE_mask_layer_shape_sort(MaskLayer *masklay)
2208 {
2209         BLI_sortlist(&masklay->splines_shapes, mask_layer_shape_sort_cb);
2210 }
2211
2212 int BKE_mask_layer_shape_spline_from_index(MaskLayer *masklay, int index,
2213                                            MaskSpline **r_masklay_shape, int *r_index)
2214 {
2215         MaskSpline *spline;
2216
2217         for (spline = masklay->splines.first; spline; spline = spline->next) {
2218                 if (index < spline->tot_point) {
2219                         *r_masklay_shape = spline;
2220                         *r_index = index;
2221                         return TRUE;
2222                 }
2223                 index -= spline->tot_point;
2224         }
2225
2226         return FALSE;
2227 }
2228
2229 int BKE_mask_layer_shape_spline_to_index(MaskLayer *masklay, MaskSpline *spline)
2230 {
2231         MaskSpline *spline_iter;
2232         int i_abs = 0;
2233         for (spline_iter = masklay->splines.first;
2234              spline_iter && spline_iter != spline;
2235              i_abs += spline_iter->tot_point, spline_iter = spline_iter->next)
2236         {
2237                 /* pass */
2238         }
2239
2240         return i_abs;
2241 }
2242
2243 /* basic 2D interpolation functions, could make more comprehensive later */
2244 static void interp_weights_uv_v2_calc(float r_uv[2], const float pt[2], const float pt_a[2], const float pt_b[2])
2245 {
2246         float pt_on_line[2];
2247         r_uv[0] = closest_to_line_v2(pt_on_line, pt, pt_a, pt_b);
2248         r_uv[1] = (len_v2v2(pt_on_line, pt) / len_v2v2(pt_a, pt_b)) *
2249                   ((line_point_side_v2(pt_a, pt_b, pt) < 0.0f) ? -1.0 : 1.0);  /* this line only sets the sign */
2250 }
2251
2252
2253 static void interp_weights_uv_v2_apply(const float uv[2], float r_pt[2], const float pt_a[2], const float pt_b[2])
2254 {
2255         const float dvec[2] = {pt_b[0] - pt_a[0],
2256                                pt_b[1] - pt_a[1]};
2257
2258         /* u */
2259         madd_v2_v2v2fl(r_pt, pt_a, dvec, uv[0]);
2260
2261         /* v */
2262         r_pt[0] += -dvec[1] * uv[1];
2263         r_pt[1] +=  dvec[0] * uv[1];
2264 }
2265
2266 /* when a now points added - resize all shapekey array  */
2267 void BKE_mask_layer_shape_changed_add(MaskLayer *masklay, int index,
2268                                       int do_init, int do_init_interpolate)
2269 {
2270         MaskLayerShape *masklay_shape;
2271
2272         /* spline index from masklay */
2273         MaskSpline *spline;
2274         int spline_point_index;
2275
2276         if (BKE_mask_layer_shape_spline_from_index(masklay, index,
2277                                                    &spline, &spline_point_index))
2278         {
2279                 /* sanity check */
2280                 /* the point has already been removed in this array so subtract one when comparing with the shapes */
2281                 int tot = BKE_mask_layer_shape_totvert(masklay) - 1;
2282
2283                 /* for interpolation */
2284                 /* TODO - assumes closed curve for now */
2285                 float uv[3][2]; /* 3x 2D handles */
2286                 const int pi_curr =   spline_point_index;
2287                 const int pi_prev = ((spline_point_index - 1) + spline->tot_point) % spline->tot_point;
2288                 const int pi_next =  (spline_point_index + 1)                      % spline->tot_point;
2289
2290                 const int index_offset = index - spline_point_index;
2291                 /* const int pi_curr_abs = index; */
2292                 const int pi_prev_abs = pi_prev + index_offset;
2293                 const int pi_next_abs = pi_next + index_offset;
2294
2295                 int i;
2296                 if (do_init_interpolate) {
2297                         for (i = 0; i < 3; i++) {
2298                                 interp_weights_uv_v2_calc(uv[i],
2299                                                           spline->points[pi_curr].bezt.vec[i],
2300                                                           spline->points[pi_prev].bezt.vec[i],
2301                                                           spline->points[pi_next].bezt.vec[i]);
2302                         }
2303                 }
2304
2305                 for (masklay_shape = masklay->splines_shapes.first;
2306                      masklay_shape;
2307                      masklay_shape = masklay_shape->next)
2308                 {
2309                         if (tot == masklay_shape->tot_vert) {
2310                                 float *data_resized;
2311
2312                                 masklay_shape->tot_vert++;
2313                                 data_resized = MEM_mallocN(masklay_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__);
2314                                 if (index > 0) {
2315                                         memcpy(data_resized,
2316                                                masklay_shape->data,
2317                                                index * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE);
2318                                 }
2319
2320                                 if (index != masklay_shape->tot_vert - 1) {
2321                                         memcpy(&data_resized[(index + 1) * MASK_OBJECT_SHAPE_ELEM_SIZE],
2322                                                masklay_shape->data + (index * MASK_OBJECT_SHAPE_ELEM_SIZE),
2323                                                (masklay_shape->tot_vert - (index + 1)) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE);
2324                                 }
2325
2326                                 if (do_init) {
2327                                         float *fp = &data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE];
2328
2329                                         mask_layer_shape_from_mask_point(&spline->points[spline_point_index].bezt, fp);
2330
2331                                         if (do_init_interpolate && spline->tot_point > 2) {
2332                                                 for (i = 0; i < 3; i++) {
2333                                                         interp_weights_uv_v2_apply(uv[i],
2334                                                                                    &fp[i * 2],
2335                                                                                    &data_resized[(pi_prev_abs * MASK_OBJECT_SHAPE_ELEM_SIZE) + (i * 2)],
2336                                                                                    &data_resized[(pi_next_abs * MASK_OBJECT_SHAPE_ELEM_SIZE) + (i * 2)]);
2337                                                 }
2338                                         }
2339                                 }
2340                                 else {
2341                                         memset(&data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE],
2342                                                0,
2343                                                sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE);
2344                                 }
2345
2346                                 MEM_freeN(masklay_shape->data);
2347                                 masklay_shape->data = data_resized;
2348                         }
2349                         else {
2350                                 printf("%s: vert mismatch %d != %d (frame %d)\n",
2351                                        __func__, masklay_shape->tot_vert, tot, masklay_shape->frame);
2352                         }
2353                 }
2354         }
2355 }
2356
2357
2358 /* move array to account for removed point */
2359 void BKE_mask_layer_shape_changed_remove(MaskLayer *masklay, int index, int count)
2360 {
2361         MaskLayerShape *masklay_shape;
2362
2363         /* the point has already been removed in this array so add one when comparing with the shapes */
2364         int tot = BKE_mask_layer_shape_totvert(masklay);
2365
2366         for (masklay_shape = masklay->splines_shapes.first;
2367              masklay_shape;
2368              masklay_shape = masklay_shape->next)
2369         {
2370                 if (tot == masklay_shape->tot_vert - count) {
2371                         float *data_resized;
2372
2373                         masklay_shape->tot_vert -= count;
2374                         data_resized = MEM_mallocN(masklay_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE, __func__);
2375                         if (index > 0) {
2376                                 memcpy(data_resized,
2377                                        masklay_shape->data,
2378                                        index * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE);
2379                         }
2380
2381                         if (index != masklay_shape->tot_vert) {
2382                                 memcpy(&data_resized[index * MASK_OBJECT_SHAPE_ELEM_SIZE],
2383                                        masklay_shape->data + ((index + count) * MASK_OBJECT_SHAPE_ELEM_SIZE),
2384                                        (masklay_shape->tot_vert - index) * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE);
2385                         }
2386
2387                         MEM_freeN(masklay_shape->data);
2388                         masklay_shape->data = data_resized;
2389                 }
2390                 else {
2391                         printf("%s: vert mismatch %d != %d (frame %d)\n",
2392                                __func__, masklay_shape->tot_vert - count, tot, masklay_shape->frame);
2393                 }
2394         }
2395 }
2396
2397 /* local functions */
2398 static void invert_vn_vn(float *array, const int size)
2399 {
2400         float *arr = array + (size - 1);
2401         int i = size;
2402         while (i--) {
2403                 *(arr) = 1.0f - *(arr);
2404                 arr--;
2405         }
2406 }
2407
2408 static void m_invert_vn_vn(float *array, const float f, const int size)
2409 {
2410         float *arr = array + (size - 1);
2411         int i = size;
2412         while (i--) {
2413                 *(arr) = 1.0f - (*(arr) * f);
2414                 arr--;
2415         }
2416 }
2417
2418 static void clamp_vn_vn(float *array, const int size)
2419 {
2420         float *arr = array + (size - 1);
2421
2422         int i = size;
2423         while (i--) {
2424                 if      (*arr < 0.0f) *arr = 0.0f;
2425                 else if (*arr > 1.0f) *arr = 1.0f;
2426                 arr--;
2427         }
2428 }
2429
2430 int BKE_mask_get_duration(Mask *mask)
2431 {
2432         return MAX2(1, mask->efra - mask->sfra);
2433 }
2434
2435 #ifdef USE_MANGO_MASK_CACHE_HACK
2436 static int mask_point_compare(MaskSplinePoint *point_a, MaskSplinePoint *point_b)
2437 {
2438         if (point_a->tot_uw != point_b->tot_uw) {
2439                 return FALSE;
2440         }
2441
2442         if (memcmp(&point_a->bezt, &point_b->bezt, sizeof(BezTriple))) {
2443                 return FALSE;
2444         }
2445
2446         if (memcmp(&point_a->uw, &point_b->uw, 2 * point_a->tot_uw * sizeof(float))) {
2447                 return FALSE;
2448         }
2449
2450         return TRUE;
2451 }
2452
2453 static int mask_points_compare(MaskSplinePoint *points_a, MaskSplinePoint *points_b, int tot_point)
2454 {
2455         MaskSplinePoint *point_a = points_a;
2456         MaskSplinePoint *point_b = points_b;
2457         int a = tot_point;
2458
2459         /* deform points can be NULL */
2460         if (point_a == NULL || point_b == NULL) {
2461                 return ((point_a == NULL) && (point_b == NULL));
2462         }
2463
2464         while (a--) {
2465                 if (!mask_point_compare(point_a, point_b)) {
2466                         return FALSE;
2467                 }
2468
2469                 point_a++;
2470                 point_b++;
2471         }
2472
2473         return TRUE;
2474 }
2475
2476 static int mask_spline_compare(MaskSpline *spline_a, MaskSpline *spline_b)
2477 {
2478         if (spline_a->flag != spline_b->flag ||
2479             spline_a->tot_point != spline_b->tot_point ||
2480             spline_a->weight_interp != spline_b->weight_interp)
2481         {
2482                 return FALSE;
2483         }
2484
2485         if (!mask_points_compare(spline_a->points, spline_b->points, spline_a->tot_point)) {
2486                 return FALSE;
2487         }
2488
2489         return mask_points_compare(spline_a->points_deform, spline_b->points_deform, spline_a->tot_point);
2490 }
2491
2492 static int mask_splines_compare(ListBase *base_a, ListBase *base_b)
2493 {
2494         MaskSpline *spline_a, *spline_b;
2495
2496         for (spline_a = base_a->first, spline_b = base_b->first;
2497              spline_a && spline_b;
2498              spline_a = spline_a->next, spline_b = spline_b->next)
2499         {
2500                 if (!mask_spline_compare(spline_a, spline_b)) {
2501                         return FALSE;
2502                 }
2503         }
2504
2505         if (spline_a || spline_b)
2506                 return FALSE;
2507
2508         return TRUE;
2509 }
2510
2511 static int mask_layer_compare(MaskLayer *layer_a, MaskLayer *layer_b)
2512 {
2513         if (layer_a->alpha != layer_b->alpha ||
2514             layer_a->blend != layer_b->blend ||
2515             layer_a->blend_flag != layer_b->blend_flag ||
2516             layer_a->flag != layer_b->flag ||
2517             layer_a->restrictflag != layer_b->restrictflag)
2518         {
2519                 return FALSE;
2520         }
2521
2522         if (strcmp(layer_a->name, layer_b->name))
2523                 return FALSE;
2524
2525         return mask_splines_compare(&layer_a->splines, &layer_b->splines);
2526 }
2527
2528 static int mask_layers_compare(ListBase *base_a, ListBase *base_b)
2529 {
2530         MaskLayer *layer_a, *layer_b;
2531
2532         for (layer_a = base_a->first, layer_b = base_b->first;
2533              layer_a && layer_b;
2534              layer_a = layer_a->next, layer_b = layer_b->next)
2535         {
2536                 if (!mask_layer_compare(layer_a, layer_b)) {
2537                         return FALSE;
2538                 }
2539         }
2540
2541         if (layer_a || layer_b)
2542                 return FALSE;
2543
2544         return TRUE;
2545 }
2546 #endif
2547
2548 /* rasterization */
2549
2550 /* XXX: mask is only passed here to access rasterization cache
2551  *      this MUST be removed as soon as tile-based rasterization would be here
2552  */
2553 void BKE_mask_rasterize_layers(Mask *mask, ListBase *masklayers, int width, int height, float *buffer,
2554                                const short do_aspect_correct, const short do_mask_aa,
2555                                const short do_feather)
2556 {
2557         MaskRasterCache *cache = mask->raster_cache;
2558         MaskLayer *masklay;
2559
2560         /* temp blending buffer */
2561         const int buffer_size = width * height;
2562         float *buffer_tmp;
2563
2564 #ifdef USE_MANGO_MASK_CACHE_HACK
2565         BLI_lock_thread(LOCK_CUSTOM1);
2566
2567         if (cache &&
2568             cache->width == width &&
2569             cache->height == height &&
2570             cache->do_aspect_correct == do_aspect_correct &&
2571             cache->do_mask_aa == do_mask_aa &&
2572             cache->do_feather == do_feather &&
2573             mask_layers_compare(&cache->layers, &mask->masklayers))
2574         {
2575                 memcpy(buffer, cache->buffer, sizeof(float) * buffer_size);
2576
2577                 BLI_unlock_thread(LOCK_CUSTOM1);
2578
2579                 return;
2580         }
2581
2582         BLI_unlock_thread(LOCK_CUSTOM1);
2583 #endif
2584
2585         buffer_tmp = MEM_mallocN(sizeof(float) * buffer_size, __func__);
2586
2587         for (masklay = masklayers->first; masklay; masklay = masklay->next) {
2588                 MaskSpline *spline;
2589                 float alpha;
2590
2591                 if (masklay->restrictflag & MASK_RESTRICT_RENDER) {
2592                         continue;
2593                 }
2594
2595                 memset(buffer_tmp, 0, sizeof(float) * buffer_size);
2596
2597                 for (spline = masklay->splines.first; spline; spline = spline->next) {
2598                         float (*diff_points)[2];
2599                         int tot_diff_point;
2600
2601                         float (*diff_feather_points)[2];
2602                         int tot_diff_feather_points;
2603
2604                         diff_points = BKE_mask_spline_differentiate_with_resolution(spline, width, height,
2605                                                                                     &tot_diff_point);
2606
2607                         if (tot_diff_point) {
2608                                 if (do_feather) {
2609                                         diff_feather_points =
2610                                                 BKE_mask_spline_feather_differentiated_points_with_resolution(spline, width, height,
2611                                                                                                               &tot_diff_feather_points);
2612                                 }
2613                                 else {
2614                                         tot_diff_feather_points = 0;
2615                                         diff_feather_points = NULL;
2616                                 }
2617
2618                                 if (do_aspect_correct) {
2619                                         if (width != height) {
2620                                                 float *fp;
2621                                                 float *ffp;
2622                                                 int i;
2623                                                 float asp;
2624
2625                                                 if (width < height) {
2626                                                         fp = &diff_points[0][0];
2627                                                         ffp = tot_diff_feather_points ? &diff_feather_points[0][0] : NULL;
2628                                                         asp = (float)width / (float)height;
2629                                                 }
2630                                                 else {
2631                                                         fp = &diff_points[0][1];
2632                                                         ffp = tot_diff_feather_points ? &diff_feather_points[0][1] : NULL;
2633                                                         asp = (float)height / (float)width;
2634                                                 }
2635
2636                                                 for (i = 0; i < tot_diff_point; i++, fp += 2) {
2637                                                         (*fp) = (((*fp) - 0.5f) / asp) + 0.5f;
2638                                                 }
2639
2640                                                 if (tot_diff_feather_points) {
2641                                                         for (i = 0; i < tot_diff_feather_points; i++, ffp += 2) {
2642                                                                 (*ffp) = (((*ffp) - 0.5f) / asp) + 0.5f;
2643                                                         }
2644                                                 }
2645                                         }
2646                                 }
2647
2648                                 if (tot_diff_point) {
2649                                         PLX_raskterize(diff_points, tot_diff_point,
2650                                    buffer_tmp, width, height,do_mask_aa);
2651
2652                                         if (tot_diff_feather_points) {
2653                                                 PLX_raskterize_feather(diff_points, tot_diff_point,
2654                                                                        diff_feather_points, tot_diff_feather_points,
2655                                                                        buffer_tmp, width, height);
2656                                                 MEM_freeN(diff_feather_points);
2657                                         }
2658
2659                                         MEM_freeN(diff_points);
2660                                 }
2661                         }
2662                 }
2663
2664                 /* blend with original */
2665                 if (masklay->blend_flag & MASK_BLENDFLAG_INVERT) {
2666                         /* apply alpha multiply before inverting */
2667                         if (masklay->alpha != 1.0f) {
2668                                 m_invert_vn_vn(buffer_tmp, masklay->alpha, buffer_size);
2669                         }
2670                         else {
2671                                 invert_vn_vn(buffer_tmp, buffer_size);
2672                         }
2673
2674                         alpha = 1.0f;
2675                 }
2676                 else {
2677                         alpha = masklay->alpha;
2678                 }
2679
2680                 switch (masklay->blend) {
2681                         case MASK_BLEND_SUBTRACT:
2682                         {
2683                                 if (alpha == 1.0f) {
2684                                         sub_vn_vn(buffer, buffer_tmp, buffer_size);
2685                                 }
2686                                 else {
2687                                         msub_vn_vn(buffer, buffer_tmp, alpha, buffer_size);
2688                                 }
2689                                 break;
2690                         }
2691                         case MASK_BLEND_ADD:
2692                         default:
2693                         {
2694                                 if (alpha == 1.0f) {
2695                                         add_vn_vn(buffer, buffer_tmp, buffer_size);
2696                                 }
2697                                 else {
2698                                         madd_vn_vn(buffer, buffer_tmp, alpha, buffer_size);
2699                                 }
2700                                 break;
2701                         }
2702                 }
2703
2704                 if(do_mask_aa){
2705                         //PLX_antialias_buffer(buffer,width,height);
2706                 }
2707                 /* clamp at the end */
2708                 clamp_vn_vn(buffer, buffer_size);
2709         }
2710         MEM_freeN(buffer_tmp);
2711
2712 #ifdef USE_MANGO_MASK_CACHE_HACK
2713         BLI_lock_thread(LOCK_CUSTOM1);
2714
2715         BKE_mask_raster_cache_free(mask);
2716
2717         cache = MEM_callocN(sizeof(MaskRasterCache), "mask raster cache");
2718
2719         cache->buffer = MEM_mallocN(sizeof(float) * buffer_size, "mask raster cache buffer");
2720
2721         BKE_mask_layer_copy_list(&cache->layers, masklayers);
2722
2723         memcpy(cache->buffer, buffer, sizeof(float) * buffer_size);
2724
2725         cache->width = width;
2726         cache->height = height;
2727         cache->do_aspect_correct = do_aspect_correct;
2728         cache->do_mask_aa = do_mask_aa;
2729         cache->do_feather = do_feather;
2730
2731         mask->raster_cache = cache;
2732
2733         BLI_unlock_thread(LOCK_CUSTOM1);
2734 #endif
2735 }
2736
2737 #ifdef __PLX_RASKTER_MT__
2738 void BKE_mask_init_layers(Mask *mask, struct layer_init_data *mlayer_data, int width, int height, const short do_aspect_correct){
2739         MaskLayer *masklay;
2740         int numLayers=0;
2741         int currLayer=0;
2742         for (masklay = mask->masklayers->first; masklay; masklay = masklay->next) {
2743                 numLayers++;
2744         }
2745         mlayer_data = MEM_mallocN(sizeof(struct layer_init_data) * numLayers, __func__); //size correct?
2746         
2747         
2748         for (masklay = mask->masklayers->first; masklay; masklay = masklay->next) {
2749                 MaskSpline *spline;
2750                 for (spline = masklay->splines.first; spline; spline = spline->next) {
2751                         float (*diff_points)[2];
2752                         int tot_diff_point;
2753
2754                         float (*diff_feather_points)[2];
2755                         int tot_diff_feather_points;
2756
2757                         diff_points = BKE_mask_spline_differentiate_with_resolution(spline, width, height,
2758                                                                                     &tot_diff_point);
2759
2760                         if (tot_diff_point) {
2761                                 if (do_feather) {
2762                                         diff_feather_points =
2763                                                 BKE_mask_spline_feather_differentiated_points_with_resolution(spline, width, height,
2764                                                                                                               &tot_diff_feather_points);
2765                                 }
2766                                 else {
2767                                         tot_diff_feather_points = 0;
2768                                         diff_feather_points = NULL;
2769                                 }
2770
2771                                 if (do_aspect_correct) {
2772                                         if (width != height) {
2773                                                 float *fp;
2774                                                 float *ffp;
2775                                                 int i;
2776                                                 float asp;
2777
2778                                                 if (width < height) {
2779                                                         fp = &diff_points[0][0];
2780                                                         ffp = tot_diff_feather_points ? &diff_feather_points[0][0] : NULL;
2781                                                         asp = (float)width / (float)height;
2782                                                 }
2783                                                 else {
2784                                                         fp = &diff_points[0][1];
2785                                                         ffp = tot_diff_feather_points ? &diff_feather_points[0][1] : NULL;
2786                                                         asp = (float)height / (float)width;
2787                                                 }
2788
2789                                                 for (i = 0; i < tot_diff_point; i++, fp += 2) {
2790                                                         (*fp) = (((*fp) - 0.5f) / asp) + 0.5f;
2791                                                 }
2792
2793                                                 if (tot_diff_feather_points) {
2794                                                         for (i = 0; i < tot_diff_feather_points; i++, ffp += 2) {
2795                                                                 (*ffp) = (((*ffp) - 0.5f) / asp) + 0.5f;
2796                                                         }
2797                                                 }
2798                                         }
2799                                 }
2800                                 PLX_init_base_data(mlayer_data[currLayer], diff_points, tot_diff_points, width, height);
2801                                 currLayer++;
2802                         }
2803                 }
2804         }
2805 }
2806 #endif
2807
2808 void BKE_mask_rasterize(Mask *mask, int width, int height, float *buffer,
2809                         const short do_aspect_correct, const short do_mask_aa,
2810                         const short do_feather)
2811 {
2812         BKE_mask_rasterize_layers(mask, &mask->masklayers, width, height, buffer, do_aspect_correct, do_mask_aa, do_feather);
2813 }