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