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