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