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