Merge branch 'blender-v2.81-release'
[blender.git] / source / blender / makesrna / intern / rna_mask.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16
17 /** \file
18  * \ingroup RNA
19  */
20
21 #include <stdlib.h>
22 #include <limits.h>
23
24 #include "MEM_guardedalloc.h"
25
26 #include "DNA_mask_types.h"
27 #include "DNA_object_types.h" /* SELECT */
28 #include "DNA_scene_types.h"
29
30 #include "BLT_translation.h"
31
32 #include "BKE_movieclip.h"
33 #include "BKE_tracking.h"
34
35 #include "RNA_define.h"
36 #include "RNA_enum_types.h"
37
38 #include "rna_internal.h"
39
40 #include "WM_types.h"
41
42 #include "IMB_imbuf_types.h"
43 #include "IMB_imbuf.h"
44
45 #ifdef RNA_RUNTIME
46
47 #  include "BLI_math.h"
48
49 #  include "DNA_movieclip_types.h"
50
51 #  include "BKE_mask.h"
52
53 #  include "DEG_depsgraph.h"
54
55 #  include "RNA_access.h"
56
57 #  include "WM_api.h"
58
59 static void rna_Mask_update_data(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
60 {
61   Mask *mask = (Mask *)ptr->owner_id;
62
63   WM_main_add_notifier(NC_MASK | ND_DATA, mask);
64   DEG_id_tag_update(&mask->id, 0);
65 }
66
67 static void rna_Mask_update_parent(Main *bmain, Scene *scene, PointerRNA *ptr)
68 {
69   MaskParent *parent = ptr->data;
70
71   if (parent->id) {
72     if (GS(parent->id->name) == ID_MC) {
73       MovieClip *clip = (MovieClip *)parent->id;
74       MovieTracking *tracking = &clip->tracking;
75       MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, parent->parent);
76
77       if (object) {
78         int clip_framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, scene->r.cfra);
79
80         if (parent->type == MASK_PARENT_POINT_TRACK) {
81           MovieTrackingTrack *track = BKE_tracking_track_get_named(
82               tracking, object, parent->sub_parent);
83
84           if (track) {
85             MovieTrackingMarker *marker = BKE_tracking_marker_get(track, clip_framenr);
86             float marker_pos_ofs[2], parmask_pos[2];
87             MovieClipUser user = {0};
88
89             BKE_movieclip_user_set_frame(&user, scene->r.cfra);
90
91             add_v2_v2v2(marker_pos_ofs, marker->pos, track->offset);
92
93             BKE_mask_coord_from_movieclip(clip, &user, parmask_pos, marker_pos_ofs);
94
95             copy_v2_v2(parent->parent_orig, parmask_pos);
96           }
97         }
98         else /* if (parent->type == MASK_PARENT_PLANE_TRACK) */ {
99           MovieTrackingPlaneTrack *plane_track = BKE_tracking_plane_track_get_named(
100               tracking, object, parent->sub_parent);
101           if (plane_track) {
102             MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track,
103                                                                                    clip_framenr);
104
105             memcpy(parent->parent_corners_orig,
106                    plane_marker->corners,
107                    sizeof(parent->parent_corners_orig));
108             zero_v2(parent->parent_orig);
109           }
110         }
111       }
112     }
113   }
114
115   rna_Mask_update_data(bmain, scene, ptr);
116 }
117
118 /* note: this function exists only to avoid id refcounting */
119 static void rna_MaskParent_id_set(PointerRNA *ptr,
120                                   PointerRNA value,
121                                   struct ReportList *UNUSED(reports))
122 {
123   MaskParent *mpar = (MaskParent *)ptr->data;
124
125   mpar->id = value.data;
126 }
127
128 static StructRNA *rna_MaskParent_id_typef(PointerRNA *ptr)
129 {
130   MaskParent *mpar = (MaskParent *)ptr->data;
131
132   return ID_code_to_RNA_type(mpar->id_type);
133 }
134
135 static void rna_MaskParent_id_type_set(PointerRNA *ptr, int value)
136 {
137   MaskParent *mpar = (MaskParent *)ptr->data;
138
139   /* change ID-type to the new type */
140   mpar->id_type = value;
141
142   /* clear the id-block if the type is invalid */
143   if ((mpar->id) && (GS(mpar->id->name) != mpar->id_type)) {
144     mpar->id = NULL;
145   }
146 }
147
148 static void rna_Mask_layers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
149 {
150   Mask *mask = (Mask *)ptr->owner_id;
151
152   rna_iterator_listbase_begin(iter, &mask->masklayers, NULL);
153 }
154
155 static int rna_Mask_layer_active_index_get(PointerRNA *ptr)
156 {
157   Mask *mask = (Mask *)ptr->owner_id;
158
159   return mask->masklay_act;
160 }
161
162 static void rna_Mask_layer_active_index_set(PointerRNA *ptr, int value)
163 {
164   Mask *mask = (Mask *)ptr->owner_id;
165
166   mask->masklay_act = value;
167 }
168
169 static void rna_Mask_layer_active_index_range(
170     PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
171 {
172   Mask *mask = (Mask *)ptr->owner_id;
173
174   *min = 0;
175   *max = max_ii(0, mask->masklay_tot - 1);
176
177   *softmin = *min;
178   *softmax = *max;
179 }
180
181 static char *rna_MaskLayer_path(PointerRNA *ptr)
182 {
183   MaskLayer *masklay = (MaskLayer *)ptr->data;
184   char name_esc[sizeof(masklay->name) * 2];
185   BLI_strescape(name_esc, masklay->name, sizeof(name_esc));
186   return BLI_sprintfN("layers[\"%s\"]", name_esc);
187 }
188
189 static PointerRNA rna_Mask_layer_active_get(PointerRNA *ptr)
190 {
191   Mask *mask = (Mask *)ptr->owner_id;
192   MaskLayer *masklay = BKE_mask_layer_active(mask);
193
194   return rna_pointer_inherit_refine(ptr, &RNA_MaskLayer, masklay);
195 }
196
197 static void rna_Mask_layer_active_set(PointerRNA *ptr,
198                                       PointerRNA value,
199                                       struct ReportList *UNUSED(reports))
200 {
201   Mask *mask = (Mask *)ptr->owner_id;
202   MaskLayer *masklay = (MaskLayer *)value.data;
203
204   BKE_mask_layer_active_set(mask, masklay);
205 }
206
207 static void rna_MaskLayer_splines_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
208 {
209   MaskLayer *masklay = (MaskLayer *)ptr->data;
210
211   rna_iterator_listbase_begin(iter, &masklay->splines, NULL);
212 }
213
214 static void rna_MaskLayer_name_set(PointerRNA *ptr, const char *value)
215 {
216   Mask *mask = (Mask *)ptr->owner_id;
217   MaskLayer *masklay = (MaskLayer *)ptr->data;
218   char oldname[sizeof(masklay->name)], newname[sizeof(masklay->name)];
219
220   /* need to be on the stack */
221   BLI_strncpy(oldname, masklay->name, sizeof(masklay->name));
222   BLI_strncpy_utf8(newname, value, sizeof(masklay->name));
223
224   BKE_mask_layer_rename(mask, masklay, oldname, newname);
225 }
226
227 static PointerRNA rna_MaskLayer_active_spline_get(PointerRNA *ptr)
228 {
229   MaskLayer *masklay = (MaskLayer *)ptr->data;
230
231   return rna_pointer_inherit_refine(ptr, &RNA_MaskSpline, masklay->act_spline);
232 }
233
234 static void rna_MaskLayer_active_spline_set(PointerRNA *ptr,
235                                             PointerRNA value,
236                                             struct ReportList *UNUSED(reports))
237 {
238   MaskLayer *masklay = (MaskLayer *)ptr->data;
239   MaskSpline *spline = (MaskSpline *)value.data;
240   int index = BLI_findindex(&masklay->splines, spline);
241
242   if (index != -1) {
243     masklay->act_spline = spline;
244   }
245   else {
246     masklay->act_spline = NULL;
247   }
248 }
249
250 static PointerRNA rna_MaskLayer_active_spline_point_get(PointerRNA *ptr)
251 {
252   MaskLayer *masklay = (MaskLayer *)ptr->data;
253
254   return rna_pointer_inherit_refine(ptr, &RNA_MaskSplinePoint, masklay->act_point);
255 }
256
257 static void rna_MaskLayer_active_spline_point_set(PointerRNA *ptr,
258                                                   PointerRNA value,
259                                                   struct ReportList *UNUSED(reports))
260 {
261   MaskLayer *masklay = (MaskLayer *)ptr->data;
262   MaskSpline *spline;
263   MaskSplinePoint *point = (MaskSplinePoint *)value.data;
264
265   masklay->act_point = NULL;
266
267   for (spline = masklay->splines.first; spline; spline = spline->next) {
268     if (point >= spline->points && point < spline->points + spline->tot_point) {
269       masklay->act_point = point;
270
271       break;
272     }
273   }
274 }
275
276 static void rna_MaskSplinePoint_handle1_get(PointerRNA *ptr, float *values)
277 {
278   MaskSplinePoint *point = (MaskSplinePoint *)ptr->data;
279   BezTriple *bezt = &point->bezt;
280   copy_v2_v2(values, bezt->vec[0]);
281 }
282
283 static void rna_MaskSplinePoint_handle1_set(PointerRNA *ptr, const float *values)
284 {
285   MaskSplinePoint *point = (MaskSplinePoint *)ptr->data;
286   BezTriple *bezt = &point->bezt;
287   copy_v2_v2(bezt->vec[0], values);
288 }
289
290 static void rna_MaskSplinePoint_handle2_get(PointerRNA *ptr, float *values)
291 {
292   MaskSplinePoint *point = (MaskSplinePoint *)ptr->data;
293   BezTriple *bezt = &point->bezt;
294   copy_v2_v2(values, bezt->vec[2]);
295 }
296
297 static void rna_MaskSplinePoint_handle2_set(PointerRNA *ptr, const float *values)
298 {
299   MaskSplinePoint *point = (MaskSplinePoint *)ptr->data;
300   BezTriple *bezt = &point->bezt;
301   copy_v2_v2(bezt->vec[2], values);
302 }
303
304 static void rna_MaskSplinePoint_ctrlpoint_get(PointerRNA *ptr, float *values)
305 {
306   MaskSplinePoint *point = (MaskSplinePoint *)ptr->data;
307   BezTriple *bezt = &point->bezt;
308   copy_v2_v2(values, bezt->vec[1]);
309 }
310
311 static void rna_MaskSplinePoint_ctrlpoint_set(PointerRNA *ptr, const float *values)
312 {
313   MaskSplinePoint *point = (MaskSplinePoint *)ptr->data;
314   BezTriple *bezt = &point->bezt;
315   copy_v2_v2(bezt->vec[1], values);
316 }
317
318 static int rna_MaskSplinePoint_handle_type_get(PointerRNA *ptr)
319 {
320   MaskSplinePoint *point = (MaskSplinePoint *)ptr->data;
321   BezTriple *bezt = &point->bezt;
322
323   return bezt->h1;
324 }
325
326 static MaskSpline *mask_spline_from_point(Mask *mask, MaskSplinePoint *point)
327 {
328   MaskLayer *mask_layer;
329   for (mask_layer = mask->masklayers.first; mask_layer; mask_layer = mask_layer->next) {
330     MaskSpline *spline;
331     for (spline = mask_layer->splines.first; spline; spline = spline->next) {
332       if (point >= spline->points && point < spline->points + spline->tot_point) {
333         return spline;
334       }
335     }
336   }
337   return NULL;
338 }
339
340 static void mask_point_check_stick(MaskSplinePoint *point)
341 {
342   BezTriple *bezt = &point->bezt;
343   if (bezt->h1 == HD_ALIGN && bezt->h2 == HD_ALIGN) {
344     float vec[3];
345     sub_v3_v3v3(vec, bezt->vec[0], bezt->vec[1]);
346     add_v3_v3v3(bezt->vec[2], bezt->vec[1], vec);
347   }
348 }
349
350 static void rna_MaskSplinePoint_handle_type_set(PointerRNA *ptr, int value)
351 {
352   MaskSplinePoint *point = (MaskSplinePoint *)ptr->data;
353   BezTriple *bezt = &point->bezt;
354   MaskSpline *spline = mask_spline_from_point((Mask *)ptr->owner_id, point);
355
356   bezt->h1 = bezt->h2 = value;
357   mask_point_check_stick(point);
358   BKE_mask_calc_handle_point(spline, point);
359 }
360
361 static int rna_MaskSplinePoint_handle_left_type_get(PointerRNA *ptr)
362 {
363   MaskSplinePoint *point = (MaskSplinePoint *)ptr->data;
364   BezTriple *bezt = &point->bezt;
365
366   return bezt->h1;
367 }
368
369 static void rna_MaskSplinePoint_handle_left_type_set(PointerRNA *ptr, int value)
370 {
371   MaskSplinePoint *point = (MaskSplinePoint *)ptr->data;
372   BezTriple *bezt = &point->bezt;
373   MaskSpline *spline = mask_spline_from_point((Mask *)ptr->owner_id, point);
374
375   bezt->h1 = value;
376   mask_point_check_stick(point);
377   BKE_mask_calc_handle_point(spline, point);
378 }
379
380 static int rna_MaskSplinePoint_handle_right_type_get(PointerRNA *ptr)
381 {
382   MaskSplinePoint *point = (MaskSplinePoint *)ptr->data;
383   BezTriple *bezt = &point->bezt;
384
385   return bezt->h2;
386 }
387
388 static void rna_MaskSplinePoint_handle_right_type_set(PointerRNA *ptr, int value)
389 {
390   MaskSplinePoint *point = (MaskSplinePoint *)ptr->data;
391   BezTriple *bezt = &point->bezt;
392   MaskSpline *spline = mask_spline_from_point((Mask *)ptr->owner_id, point);
393
394   bezt->h2 = value;
395   mask_point_check_stick(point);
396   BKE_mask_calc_handle_point(spline, point);
397 }
398
399 /* ** API **  */
400
401 static MaskLayer *rna_Mask_layers_new(Mask *mask, const char *name)
402 {
403   MaskLayer *masklay = BKE_mask_layer_new(mask, name);
404
405   WM_main_add_notifier(NC_MASK | NA_EDITED, mask);
406
407   return masklay;
408 }
409
410 static void rna_Mask_layers_remove(Mask *mask, ReportList *reports, PointerRNA *masklay_ptr)
411 {
412   MaskLayer *masklay = masklay_ptr->data;
413   if (BLI_findindex(&mask->masklayers, masklay) == -1) {
414     BKE_reportf(reports,
415                 RPT_ERROR,
416                 "Mask layer '%s' not found in mask '%s'",
417                 masklay->name,
418                 mask->id.name + 2);
419     return;
420   }
421
422   BKE_mask_layer_remove(mask, masklay);
423   RNA_POINTER_INVALIDATE(masklay_ptr);
424
425   WM_main_add_notifier(NC_MASK | NA_EDITED, mask);
426 }
427
428 static void rna_Mask_layers_clear(Mask *mask)
429 {
430   BKE_mask_layer_free_list(&mask->masklayers);
431
432   WM_main_add_notifier(NC_MASK | NA_EDITED, mask);
433 }
434
435 static MaskSpline *rna_MaskLayer_spline_new(ID *id, MaskLayer *mask_layer)
436 {
437   Mask *mask = (Mask *)id;
438   MaskSpline *new_spline;
439
440   new_spline = BKE_mask_spline_add(mask_layer);
441
442   WM_main_add_notifier(NC_MASK | NA_EDITED, mask);
443
444   return new_spline;
445 }
446
447 static void rna_MaskLayer_spline_remove(ID *id,
448                                         MaskLayer *mask_layer,
449                                         ReportList *reports,
450                                         PointerRNA *spline_ptr)
451 {
452   Mask *mask = (Mask *)id;
453   MaskSpline *spline = spline_ptr->data;
454
455   if (BKE_mask_spline_remove(mask_layer, spline) == false) {
456     BKE_reportf(
457         reports, RPT_ERROR, "Mask layer '%s' does not contain spline given", mask_layer->name);
458     return;
459   }
460
461   RNA_POINTER_INVALIDATE(spline_ptr);
462
463   DEG_id_tag_update(&mask->id, ID_RECALC_GEOMETRY);
464 }
465
466 static void rna_Mask_start_frame_set(PointerRNA *ptr, int value)
467 {
468   Mask *data = (Mask *)ptr->data;
469   /* MINFRAME not MINAFRAME, since some output formats can't taken negative frames */
470   CLAMP(value, MINFRAME, MAXFRAME);
471   data->sfra = value;
472
473   if (data->sfra >= data->efra) {
474     data->efra = MIN2(data->sfra, MAXFRAME);
475   }
476 }
477
478 static void rna_Mask_end_frame_set(PointerRNA *ptr, int value)
479 {
480   Mask *data = (Mask *)ptr->data;
481   CLAMP(value, MINFRAME, MAXFRAME);
482   data->efra = value;
483
484   if (data->sfra >= data->efra) {
485     data->sfra = MAX2(data->efra, MINFRAME);
486   }
487 }
488
489 static void rna_MaskSpline_points_add(ID *id, MaskSpline *spline, int count)
490 {
491   Mask *mask = (Mask *)id;
492   MaskLayer *layer;
493   int active_point_index = -1;
494   int i, spline_shape_index;
495
496   if (count <= 0) {
497     return;
498   }
499
500   for (layer = mask->masklayers.first; layer; layer = layer->next) {
501     if (BLI_findindex(&layer->splines, spline) != -1) {
502       break;
503     }
504   }
505
506   if (!layer) {
507     /* Shall not happen actually */
508     BLI_assert(!"No layer found for the spline");
509     return;
510   }
511
512   if (layer->act_spline == spline) {
513     active_point_index = layer->act_point - spline->points;
514   }
515
516   spline->points = MEM_recallocN(spline->points,
517                                  sizeof(MaskSplinePoint) * (spline->tot_point + count));
518   spline->tot_point += count;
519
520   if (active_point_index >= 0) {
521     layer->act_point = spline->points + active_point_index;
522   }
523
524   spline_shape_index = BKE_mask_layer_shape_spline_to_index(layer, spline);
525
526   for (i = 0; i < count; i++) {
527     int point_index = spline->tot_point - count + i;
528     MaskSplinePoint *new_point = spline->points + point_index;
529     new_point->bezt.h1 = new_point->bezt.h2 = HD_ALIGN;
530     BKE_mask_calc_handle_point_auto(spline, new_point, true);
531     BKE_mask_parent_init(&new_point->parent);
532
533     /* Not efficient, but there's no other way for now */
534     BKE_mask_layer_shape_changed_add(layer, spline_shape_index + point_index, true, true);
535   }
536
537   WM_main_add_notifier(NC_MASK | ND_DATA, mask);
538   DEG_id_tag_update(&mask->id, 0);
539 }
540
541 static void rna_MaskSpline_point_remove(ID *id,
542                                         MaskSpline *spline,
543                                         ReportList *reports,
544                                         PointerRNA *point_ptr)
545 {
546   Mask *mask = (Mask *)id;
547   MaskSplinePoint *point = point_ptr->data;
548   MaskSplinePoint *new_point_array;
549   MaskLayer *layer;
550   int active_point_index = -1;
551   int point_index;
552
553   for (layer = mask->masklayers.first; layer; layer = layer->next) {
554     if (BLI_findindex(&layer->splines, spline) != -1) {
555       break;
556     }
557   }
558
559   if (!layer) {
560     /* Shall not happen actually */
561     BKE_report(reports, RPT_ERROR, "Mask layer not found for given spline");
562     return;
563   }
564
565   if (point < spline->points || point >= spline->points + spline->tot_point) {
566     BKE_report(reports, RPT_ERROR, "Point is not found in given spline");
567     return;
568   }
569
570   if (layer->act_spline == spline) {
571     active_point_index = layer->act_point - spline->points;
572   }
573
574   point_index = point - spline->points;
575
576   new_point_array = MEM_mallocN(sizeof(MaskSplinePoint) * (spline->tot_point - 1),
577                                 "remove mask point");
578
579   memcpy(new_point_array, spline->points, sizeof(MaskSplinePoint) * point_index);
580   memcpy(new_point_array + point_index,
581          spline->points + point_index + 1,
582          sizeof(MaskSplinePoint) * (spline->tot_point - point_index - 1));
583
584   MEM_freeN(spline->points);
585   spline->points = new_point_array;
586   spline->tot_point--;
587
588   if (active_point_index >= 0) {
589     if (active_point_index == point_index) {
590       layer->act_point = NULL;
591     }
592     else if (active_point_index < point_index) {
593       layer->act_point = spline->points + active_point_index;
594     }
595     else {
596       layer->act_point = spline->points + active_point_index - 1;
597     }
598   }
599
600   BKE_mask_layer_shape_changed_remove(
601       layer, BKE_mask_layer_shape_spline_to_index(layer, spline) + point_index, 1);
602
603   WM_main_add_notifier(NC_MASK | ND_DATA, mask);
604   DEG_id_tag_update(&mask->id, 0);
605
606   RNA_POINTER_INVALIDATE(point_ptr);
607 }
608
609 #else
610 static void rna_def_maskParent(BlenderRNA *brna)
611 {
612   StructRNA *srna;
613   PropertyRNA *prop;
614
615   static const EnumPropertyItem mask_id_type_items[] = {
616       {ID_MC, "MOVIECLIP", ICON_SEQUENCE, "Movie Clip", ""},
617       {0, NULL, 0, NULL, NULL},
618   };
619
620   static const EnumPropertyItem parent_type_items[] = {
621       {MASK_PARENT_POINT_TRACK, "POINT_TRACK", 0, "Point Track", ""},
622       {MASK_PARENT_PLANE_TRACK, "PLANE_TRACK", 0, "Plane Track", ""},
623       {0, NULL, 0, NULL, NULL},
624   };
625
626   srna = RNA_def_struct(brna, "MaskParent", NULL);
627   RNA_def_struct_ui_text(srna, "Mask Parent", "Parenting settings for masking element");
628
629   /* Target Properties - ID-block to Drive */
630   prop = RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE);
631   RNA_def_property_struct_type(prop, "ID");
632   RNA_def_property_flag(prop, PROP_EDITABLE);
633   // RNA_def_property_editable_func(prop, "rna_maskSpline_id_editable");
634   /* note: custom set function is ONLY to avoid rna setting a user for this. */
635   RNA_def_property_pointer_funcs(
636       prop, NULL, "rna_MaskParent_id_set", "rna_MaskParent_id_typef", NULL);
637   RNA_def_property_ui_text(
638       prop, "ID", "ID-block to which masking element would be parented to or to it's property");
639   RNA_def_property_update(prop, 0, "rna_Mask_update_parent");
640
641   prop = RNA_def_property(srna, "id_type", PROP_ENUM, PROP_NONE);
642   RNA_def_property_enum_sdna(prop, NULL, "id_type");
643   RNA_def_property_enum_items(prop, mask_id_type_items);
644   RNA_def_property_enum_default(prop, ID_MC);
645   RNA_def_property_enum_funcs(prop, NULL, "rna_MaskParent_id_type_set", NULL);
646   // RNA_def_property_editable_func(prop, "rna_MaskParent_id_type_editable");
647   RNA_def_property_ui_text(prop, "ID Type", "Type of ID-block that can be used");
648   RNA_def_property_update(prop, 0, "rna_Mask_update_parent");
649
650   /* type */
651   prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
652   RNA_def_property_enum_items(prop, parent_type_items);
653   RNA_def_property_ui_text(prop, "Parent Type", "Parent Type");
654   RNA_def_property_update(prop, 0, "rna_Mask_update_parent");
655
656   /* parent */
657   prop = RNA_def_property(srna, "parent", PROP_STRING, PROP_NONE);
658   RNA_def_property_ui_text(
659       prop, "Parent", "Name of parent object in specified data-block to which parenting happens");
660   RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2);
661   RNA_def_property_update(prop, 0, "rna_Mask_update_parent");
662
663   /* sub_parent */
664   prop = RNA_def_property(srna, "sub_parent", PROP_STRING, PROP_NONE);
665   RNA_def_property_ui_text(
666       prop,
667       "Sub Parent",
668       "Name of parent sub-object in specified data-block to which parenting happens");
669   RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2);
670   RNA_def_property_update(prop, 0, "rna_Mask_update_parent");
671 }
672
673 static void rna_def_maskSplinePointUW(BlenderRNA *brna)
674 {
675   StructRNA *srna;
676   PropertyRNA *prop;
677
678   srna = RNA_def_struct(brna, "MaskSplinePointUW", NULL);
679   RNA_def_struct_ui_text(
680       srna, "Mask Spline UW Point", "Single point in spline segment defining feather");
681
682   /* u */
683   prop = RNA_def_property(srna, "u", PROP_FLOAT, PROP_NONE);
684   RNA_def_property_float_sdna(prop, NULL, "u");
685   RNA_def_property_range(prop, 0.0, 1.0);
686   RNA_def_property_ui_text(prop, "U", "U coordinate of point along spline segment");
687   RNA_def_property_update(prop, 0, "rna_Mask_update_data");
688
689   /* weight */
690   prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_NONE);
691   RNA_def_property_float_sdna(prop, NULL, "w");
692   RNA_def_property_range(prop, 0.0, 1.0);
693   RNA_def_property_ui_text(prop, "Weight", "Weight of feather point");
694   RNA_def_property_update(prop, 0, "rna_Mask_update_data");
695
696   /* select */
697   prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
698   RNA_def_property_boolean_sdna(prop, NULL, "flag", SELECT);
699   RNA_def_property_ui_text(prop, "Select", "Selection status");
700   RNA_def_property_update(prop, 0, "rna_Mask_update_data");
701 }
702
703 static void rna_def_maskSplinePoint(BlenderRNA *brna)
704 {
705   StructRNA *srna;
706   PropertyRNA *prop;
707
708   static const EnumPropertyItem handle_type_items[] = {
709       {HD_AUTO, "AUTO", 0, "Auto", ""},
710       {HD_VECT, "VECTOR", 0, "Vector", ""},
711       {HD_ALIGN, "ALIGNED", 0, "Aligned Single", ""},
712       {HD_ALIGN_DOUBLESIDE, "ALIGNED_DOUBLESIDE", 0, "Aligned", ""},
713       {HD_FREE, "FREE", 0, "Free", ""},
714       {0, NULL, 0, NULL, NULL},
715   };
716
717   rna_def_maskSplinePointUW(brna);
718
719   srna = RNA_def_struct(brna, "MaskSplinePoint", NULL);
720   RNA_def_struct_ui_text(
721       srna, "Mask Spline Point", "Single point in spline used for defining mask");
722
723   /* Vector values */
724   prop = RNA_def_property(srna, "handle_left", PROP_FLOAT, PROP_TRANSLATION);
725   RNA_def_property_array(prop, 2);
726   RNA_def_property_float_funcs(
727       prop, "rna_MaskSplinePoint_handle1_get", "rna_MaskSplinePoint_handle1_set", NULL);
728   RNA_def_property_ui_text(prop, "Handle 1", "Coordinates of the first handle");
729   RNA_def_property_update(prop, 0, "rna_Mask_update_data");
730
731   prop = RNA_def_property(srna, "co", PROP_FLOAT, PROP_TRANSLATION);
732   RNA_def_property_array(prop, 2);
733   RNA_def_property_float_funcs(
734       prop, "rna_MaskSplinePoint_ctrlpoint_get", "rna_MaskSplinePoint_ctrlpoint_set", NULL);
735   RNA_def_property_ui_text(prop, "Control Point", "Coordinates of the control point");
736   RNA_def_property_update(prop, 0, "rna_Mask_update_data");
737
738   prop = RNA_def_property(srna, "handle_right", PROP_FLOAT, PROP_TRANSLATION);
739   RNA_def_property_array(prop, 2);
740   RNA_def_property_float_funcs(
741       prop, "rna_MaskSplinePoint_handle2_get", "rna_MaskSplinePoint_handle2_set", NULL);
742   RNA_def_property_ui_text(prop, "Handle 2", "Coordinates of the second handle");
743   RNA_def_property_update(prop, 0, "rna_Mask_update_data");
744
745   /* handle_type */
746   prop = RNA_def_property(srna, "handle_type", PROP_ENUM, PROP_NONE);
747   RNA_def_property_enum_funcs(
748       prop, "rna_MaskSplinePoint_handle_type_get", "rna_MaskSplinePoint_handle_type_set", NULL);
749   RNA_def_property_enum_items(prop, handle_type_items);
750   RNA_def_property_ui_text(prop, "Handle Type", "Handle type");
751   RNA_def_property_update(prop, 0, "rna_Mask_update_data");
752
753   /* handle_type */
754   prop = RNA_def_property(srna, "handle_left_type", PROP_ENUM, PROP_NONE);
755   RNA_def_property_enum_funcs(prop,
756                               "rna_MaskSplinePoint_handle_left_type_get",
757                               "rna_MaskSplinePoint_handle_left_type_set",
758                               NULL);
759   RNA_def_property_enum_items(prop, handle_type_items);
760   RNA_def_property_ui_text(prop, "Handle 1 Type", "Handle type");
761   RNA_def_property_update(prop, 0, "rna_Mask_update_data");
762
763   /* handle_right */
764   prop = RNA_def_property(srna, "handle_right_type", PROP_ENUM, PROP_NONE);
765   RNA_def_property_enum_funcs(prop,
766                               "rna_MaskSplinePoint_handle_right_type_get",
767                               "rna_MaskSplinePoint_handle_right_type_set",
768                               NULL);
769   RNA_def_property_enum_items(prop, handle_type_items);
770   RNA_def_property_ui_text(prop, "Handle 2 Type", "Handle type");
771   RNA_def_property_update(prop, 0, "rna_Mask_update_data");
772
773   /* weight */
774   prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_NONE);
775   RNA_def_property_float_sdna(prop, NULL, "bezt.weight");
776   RNA_def_property_range(prop, 0.0, 1.0);
777   RNA_def_property_ui_text(prop, "Weight", "Weight of the point");
778   RNA_def_property_update(prop, 0, "rna_Mask_update_data");
779
780   /* select */
781   prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
782   RNA_def_property_boolean_sdna(prop, NULL, "bezt.f1", SELECT);
783   RNA_def_property_ui_text(prop, "Select", "Selection status");
784   RNA_def_property_update(prop, 0, "rna_Mask_update_data");
785
786   /* parent */
787   prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
788   RNA_def_property_struct_type(prop, "MaskParent");
789
790   /* feather points */
791   prop = RNA_def_property(srna, "feather_points", PROP_COLLECTION, PROP_NONE);
792   RNA_def_property_struct_type(prop, "MaskSplinePointUW");
793   RNA_def_property_collection_sdna(prop, NULL, "uw", "tot_uw");
794   RNA_def_property_ui_text(prop, "Feather Points", "Points defining feather");
795 }
796
797 static void rna_def_mask_splines(BlenderRNA *brna)
798 {
799   StructRNA *srna;
800   FunctionRNA *func;
801   PropertyRNA *prop;
802   PropertyRNA *parm;
803
804   srna = RNA_def_struct(brna, "MaskSplines", NULL);
805   RNA_def_struct_sdna(srna, "MaskLayer");
806   RNA_def_struct_ui_text(srna, "Mask Splines", "Collection of masking splines");
807
808   /* Create new spline */
809   func = RNA_def_function(srna, "new", "rna_MaskLayer_spline_new");
810   RNA_def_function_flag(func, FUNC_USE_SELF_ID);
811   RNA_def_function_ui_description(func, "Add a new spline to the layer");
812   parm = RNA_def_pointer(func, "spline", "MaskSpline", "", "The newly created spline");
813   RNA_def_function_return(func, parm);
814
815   /* Remove the spline */
816   func = RNA_def_function(srna, "remove", "rna_MaskLayer_spline_remove");
817   RNA_def_function_flag(func, FUNC_USE_SELF_ID);
818   RNA_def_function_ui_description(func, "Remove a spline from a layer");
819   RNA_def_function_flag(func, FUNC_USE_REPORTS);
820   parm = RNA_def_pointer(func, "spline", "MaskSpline", "", "The spline to remove");
821   RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
822   RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
823
824   /* active spline */
825   prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
826   RNA_def_property_struct_type(prop, "MaskSpline");
827   RNA_def_property_pointer_funcs(
828       prop, "rna_MaskLayer_active_spline_get", "rna_MaskLayer_active_spline_set", NULL, NULL);
829   RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
830   RNA_def_property_ui_text(prop, "Active Spline", "Active spline of masking layer");
831
832   /* active point */
833   prop = RNA_def_property(srna, "active_point", PROP_POINTER, PROP_NONE);
834   RNA_def_property_struct_type(prop, "MaskSplinePoint");
835   RNA_def_property_pointer_funcs(prop,
836                                  "rna_MaskLayer_active_spline_point_get",
837                                  "rna_MaskLayer_active_spline_point_set",
838                                  NULL,
839                                  NULL);
840   RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
841   RNA_def_property_ui_text(prop, "Active Spline", "Active spline of masking layer");
842 }
843
844 static void rna_def_maskSplinePoints(BlenderRNA *brna)
845 {
846   StructRNA *srna;
847   FunctionRNA *func;
848   PropertyRNA *parm;
849
850   srna = RNA_def_struct(brna, "MaskSplinePoints", NULL);
851   RNA_def_struct_sdna(srna, "MaskSpline");
852   RNA_def_struct_ui_text(srna, "Mask Spline Points", "Collection of masking spline points");
853
854   /* Create new point */
855   func = RNA_def_function(srna, "add", "rna_MaskSpline_points_add");
856   RNA_def_function_flag(func, FUNC_USE_SELF_ID);
857   RNA_def_function_ui_description(func, "Add a number of point to this spline");
858   parm = RNA_def_int(
859       func, "count", 1, 0, INT_MAX, "Number", "Number of points to add to the spline", 0, INT_MAX);
860   RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
861
862   /* Remove the point */
863   func = RNA_def_function(srna, "remove", "rna_MaskSpline_point_remove");
864   RNA_def_function_flag(func, FUNC_USE_SELF_ID);
865   RNA_def_function_ui_description(func, "Remove a point from a spline");
866   RNA_def_function_flag(func, FUNC_USE_REPORTS);
867   parm = RNA_def_pointer(func, "point", "MaskSplinePoint", "", "The point to remove");
868   RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
869   RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
870 }
871
872 static void rna_def_maskSpline(BlenderRNA *brna)
873 {
874   static const EnumPropertyItem spline_interpolation_items[] = {
875       {MASK_SPLINE_INTERP_LINEAR, "LINEAR", 0, "Linear", ""},
876       {MASK_SPLINE_INTERP_EASE, "EASE", 0, "Ease", ""},
877       {0, NULL, 0, NULL, NULL},
878   };
879
880   static const EnumPropertyItem spline_offset_mode_items[] = {
881       {MASK_SPLINE_OFFSET_EVEN, "EVEN", 0, "Even", "Calculate even feather offset"},
882       {MASK_SPLINE_OFFSET_SMOOTH,
883        "SMOOTH",
884        0,
885        "Smooth",
886        "Calculate feather offset as a second curve"},
887       {0, NULL, 0, NULL, NULL},
888   };
889
890   StructRNA *srna;
891   PropertyRNA *prop;
892
893   rna_def_maskSplinePoint(brna);
894
895   srna = RNA_def_struct(brna, "MaskSpline", NULL);
896   RNA_def_struct_ui_text(srna, "Mask spline", "Single spline used for defining mask shape");
897
898   /* offset mode */
899   prop = RNA_def_property(srna, "offset_mode", PROP_ENUM, PROP_NONE);
900   RNA_def_property_enum_sdna(prop, NULL, "offset_mode");
901   RNA_def_property_enum_items(prop, spline_offset_mode_items);
902   RNA_def_property_ui_text(
903       prop, "Feather Offset", "The method used for calculating the feather offset");
904   RNA_def_property_update(prop, 0, "rna_Mask_update_data");
905
906   /* weight interpolation */
907   prop = RNA_def_property(srna, "weight_interpolation", PROP_ENUM, PROP_NONE);
908   RNA_def_property_enum_sdna(prop, NULL, "weight_interp");
909   RNA_def_property_enum_items(prop, spline_interpolation_items);
910   RNA_def_property_ui_text(
911       prop, "Weight Interpolation", "The type of weight interpolation for spline");
912   RNA_def_property_update(prop, 0, "rna_Mask_update_data");
913
914   /* cyclic */
915   prop = RNA_def_property(srna, "use_cyclic", PROP_BOOLEAN, PROP_NONE);
916   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
917   RNA_def_property_boolean_sdna(prop, NULL, "flag", MASK_SPLINE_CYCLIC);
918   RNA_def_property_ui_text(prop, "Cyclic", "Make this spline a closed loop");
919   RNA_def_property_update(prop, NC_MASK | NA_EDITED, "rna_Mask_update_data");
920
921   /* fill */
922   prop = RNA_def_property(srna, "use_fill", PROP_BOOLEAN, PROP_NONE);
923   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
924   RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", MASK_SPLINE_NOFILL);
925   RNA_def_property_ui_text(prop, "Fill", "Make this spline filled");
926   RNA_def_property_update(prop, NC_MASK | NA_EDITED, "rna_Mask_update_data");
927
928   /* self-intersection check */
929   prop = RNA_def_property(srna, "use_self_intersection_check", PROP_BOOLEAN, PROP_NONE);
930   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
931   RNA_def_property_boolean_sdna(prop, NULL, "flag", MASK_SPLINE_NOINTERSECT);
932   RNA_def_property_ui_text(
933       prop, "Self Intersection Check", "Prevent feather from self-intersections");
934   RNA_def_property_update(prop, NC_MASK | NA_EDITED, "rna_Mask_update_data");
935
936   prop = RNA_def_property(srna, "points", PROP_COLLECTION, PROP_NONE);
937   RNA_def_property_struct_type(prop, "MaskSplinePoint");
938   RNA_def_property_collection_sdna(prop, NULL, "points", "tot_point");
939   RNA_def_property_ui_text(prop, "Points", "Collection of points");
940   RNA_def_property_srna(prop, "MaskSplinePoints");
941 }
942
943 static void rna_def_mask_layer(BlenderRNA *brna)
944 {
945   static const EnumPropertyItem masklay_blend_mode_items[] = {
946       {MASK_BLEND_MERGE_ADD, "MERGE_ADD", 0, "Merge Add", ""},
947       {MASK_BLEND_MERGE_SUBTRACT, "MERGE_SUBTRACT", 0, "Merge Subtract", ""},
948       {MASK_BLEND_ADD, "ADD", 0, "Add", ""},
949       {MASK_BLEND_SUBTRACT, "SUBTRACT", 0, "Subtract", ""},
950       {MASK_BLEND_LIGHTEN, "LIGHTEN", 0, "Lighten", ""},
951       {MASK_BLEND_DARKEN, "DARKEN", 0, "Darken", ""},
952       {MASK_BLEND_MUL, "MUL", 0, "Multiply", ""},
953       {MASK_BLEND_REPLACE, "REPLACE", 0, "Replace", ""},
954       {MASK_BLEND_DIFFERENCE, "DIFFERENCE", 0, "Difference", ""},
955       {0, NULL, 0, NULL, NULL},
956   };
957
958   StructRNA *srna;
959   PropertyRNA *prop;
960
961   rna_def_maskSpline(brna);
962   rna_def_mask_splines(brna);
963   rna_def_maskSplinePoints(brna);
964
965   srna = RNA_def_struct(brna, "MaskLayer", NULL);
966   RNA_def_struct_ui_text(srna, "Mask Layer", "Single layer used for masking pixels");
967   RNA_def_struct_path_func(srna, "rna_MaskLayer_path");
968
969   /* name */
970   prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
971   RNA_def_property_ui_text(prop, "Name", "Unique name of layer");
972   RNA_def_property_string_funcs(prop, NULL, NULL, "rna_MaskLayer_name_set");
973   RNA_def_property_string_maxlength(prop, MAX_ID_NAME - 2);
974   RNA_def_property_update(prop, 0, "rna_Mask_update_data");
975   RNA_def_struct_name_property(srna, prop);
976
977   /* splines */
978   prop = RNA_def_property(srna, "splines", PROP_COLLECTION, PROP_NONE);
979   RNA_def_property_collection_funcs(prop,
980                                     "rna_MaskLayer_splines_begin",
981                                     "rna_iterator_listbase_next",
982                                     "rna_iterator_listbase_end",
983                                     "rna_iterator_listbase_get",
984                                     NULL,
985                                     NULL,
986                                     NULL,
987                                     NULL);
988   RNA_def_property_struct_type(prop, "MaskSpline");
989   RNA_def_property_ui_text(prop, "Splines", "Collection of splines which defines this layer");
990   RNA_def_property_srna(prop, "MaskSplines");
991
992   /* restrict */
993   prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
994   RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", MASK_RESTRICT_VIEW);
995   RNA_def_property_ui_text(prop, "Restrict View", "Restrict visibility in the viewport");
996   RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, -1);
997   RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL);
998
999   prop = RNA_def_property(srna, "hide_select", PROP_BOOLEAN, PROP_NONE);
1000   RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", MASK_RESTRICT_SELECT);
1001   RNA_def_property_ui_text(prop, "Restrict Select", "Restrict selection in the viewport");
1002   RNA_def_property_ui_icon(prop, ICON_RESTRICT_SELECT_OFF, -1);
1003   RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL);
1004
1005   prop = RNA_def_property(srna, "hide_render", PROP_BOOLEAN, PROP_NONE);
1006   RNA_def_property_boolean_sdna(prop, NULL, "restrictflag", MASK_RESTRICT_RENDER);
1007   RNA_def_property_ui_text(prop, "Restrict Render", "Restrict renderability");
1008   RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, -1);
1009   RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL);
1010
1011   /* select (for dopesheet)*/
1012   prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
1013   RNA_def_property_boolean_sdna(prop, NULL, "flag", MASK_LAYERFLAG_SELECT);
1014   RNA_def_property_ui_text(prop, "Select", "Layer is selected for editing in the Dope Sheet");
1015   //  RNA_def_property_update(prop, NC_SCREEN | ND_MASK, NULL);
1016
1017   /* render settings */
1018   prop = RNA_def_property(srna, "alpha", PROP_FLOAT, PROP_NONE);
1019   RNA_def_property_float_sdna(prop, NULL, "alpha");
1020   RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
1021   RNA_def_property_ui_text(prop, "Opacity", "Render Opacity");
1022   RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL);
1023
1024   /* weight interpolation */
1025   prop = RNA_def_property(srna, "blend", PROP_ENUM, PROP_NONE);
1026   RNA_def_property_enum_sdna(prop, NULL, "blend");
1027   RNA_def_property_enum_items(prop, masklay_blend_mode_items);
1028   RNA_def_property_ui_text(prop, "Blend", "Method of blending mask layers");
1029   RNA_def_property_update(prop, 0, "rna_Mask_update_data");
1030   RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL);
1031
1032   prop = RNA_def_property(srna, "invert", PROP_BOOLEAN, PROP_NONE);
1033   RNA_def_property_boolean_sdna(prop, NULL, "blend_flag", MASK_BLENDFLAG_INVERT);
1034   RNA_def_property_ui_text(prop, "Restrict View", "Invert the mask black/white");
1035   RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL);
1036
1037   prop = RNA_def_property(srna, "falloff", PROP_ENUM, PROP_NONE);
1038   RNA_def_property_enum_sdna(prop, NULL, "falloff");
1039   RNA_def_property_enum_items(prop, rna_enum_proportional_falloff_curve_only_items);
1040   RNA_def_property_ui_text(prop, "Falloff", "Falloff type the feather");
1041   RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */
1042   RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL);
1043
1044   /* filling options */
1045   prop = RNA_def_property(srna, "use_fill_holes", PROP_BOOLEAN, PROP_NONE);
1046   RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", MASK_LAYERFLAG_FILL_DISCRETE);
1047   RNA_def_property_ui_text(
1048       prop, "Calculate Holes", "Calculate holes when filling overlapping curves");
1049   RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL);
1050
1051   prop = RNA_def_property(srna, "use_fill_overlap", PROP_BOOLEAN, PROP_NONE);
1052   RNA_def_property_boolean_sdna(prop, NULL, "flag", MASK_LAYERFLAG_FILL_OVERLAP);
1053   RNA_def_property_ui_text(
1054       prop, "Calculate Overlap", "Calculate self intersections and overlap before filling");
1055   RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL);
1056 }
1057
1058 static void rna_def_masklayers(BlenderRNA *brna, PropertyRNA *cprop)
1059 {
1060   StructRNA *srna;
1061   PropertyRNA *prop;
1062
1063   FunctionRNA *func;
1064   PropertyRNA *parm;
1065
1066   RNA_def_property_srna(cprop, "MaskLayers");
1067   srna = RNA_def_struct(brna, "MaskLayers", NULL);
1068   RNA_def_struct_sdna(srna, "Mask");
1069   RNA_def_struct_ui_text(srna, "Mask Layers", "Collection of layers used by mask");
1070
1071   func = RNA_def_function(srna, "new", "rna_Mask_layers_new");
1072   RNA_def_function_ui_description(func, "Add layer to this mask");
1073   RNA_def_string(func, "name", NULL, 0, "Name", "Name of new layer");
1074   parm = RNA_def_pointer(func, "layer", "MaskLayer", "", "New mask layer");
1075   RNA_def_function_return(func, parm);
1076
1077   func = RNA_def_function(srna, "remove", "rna_Mask_layers_remove");
1078   RNA_def_function_flag(func, FUNC_USE_REPORTS);
1079   RNA_def_function_ui_description(func, "Remove layer from this mask");
1080   parm = RNA_def_pointer(func, "layer", "MaskLayer", "", "Shape to be removed");
1081   RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
1082   RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
1083
1084   /* clear all layers */
1085   func = RNA_def_function(srna, "clear", "rna_Mask_layers_clear");
1086   RNA_def_function_ui_description(func, "Remove all mask layers");
1087
1088   /* active layer */
1089   prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
1090   RNA_def_property_struct_type(prop, "MaskLayer");
1091   RNA_def_property_pointer_funcs(
1092       prop, "rna_Mask_layer_active_get", "rna_Mask_layer_active_set", NULL, NULL);
1093   RNA_def_property_flag(prop, PROP_EDITABLE | PROP_NEVER_UNLINK);
1094   RNA_def_property_ui_text(prop, "Active Shape", "Active layer in this mask");
1095 }
1096
1097 static void rna_def_mask(BlenderRNA *brna)
1098 {
1099   StructRNA *srna;
1100   PropertyRNA *prop;
1101
1102   rna_def_mask_layer(brna);
1103
1104   srna = RNA_def_struct(brna, "Mask", "ID");
1105   RNA_def_struct_ui_text(srna, "Mask", "Mask data-block defining mask for compositing");
1106   RNA_def_struct_ui_icon(srna, ICON_MOD_MASK);
1107
1108   /* mask layers */
1109   prop = RNA_def_property(srna, "layers", PROP_COLLECTION, PROP_NONE);
1110   RNA_def_property_collection_funcs(prop,
1111                                     "rna_Mask_layers_begin",
1112                                     "rna_iterator_listbase_next",
1113                                     "rna_iterator_listbase_end",
1114                                     "rna_iterator_listbase_get",
1115                                     NULL,
1116                                     NULL,
1117                                     NULL,
1118                                     NULL);
1119   RNA_def_property_struct_type(prop, "MaskLayer");
1120   RNA_def_property_ui_text(prop, "Layers", "Collection of layers which defines this mask");
1121   rna_def_masklayers(brna, prop);
1122
1123   /* active masklay index */
1124   prop = RNA_def_property(srna, "active_layer_index", PROP_INT, PROP_NONE);
1125   RNA_def_property_int_sdna(prop, NULL, "masklay_act");
1126   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1127   RNA_def_property_int_funcs(prop,
1128                              "rna_Mask_layer_active_index_get",
1129                              "rna_Mask_layer_active_index_set",
1130                              "rna_Mask_layer_active_index_range");
1131   RNA_def_property_ui_text(
1132       prop, "Active Shape Index", "Index of active layer in list of all mask's layers");
1133   RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL);
1134
1135   /* frame range */
1136   prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME);
1137   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1138   RNA_def_property_int_sdna(prop, NULL, "sfra");
1139   RNA_def_property_int_funcs(prop, NULL, "rna_Mask_start_frame_set", NULL);
1140   RNA_def_property_range(prop, MINFRAME, MAXFRAME);
1141   RNA_def_property_ui_text(prop, "Start Frame", "First frame of the mask (used for sequencer)");
1142   RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL);
1143
1144   prop = RNA_def_property(srna, "frame_end", PROP_INT, PROP_TIME);
1145   RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1146   RNA_def_property_int_sdna(prop, NULL, "efra");
1147   RNA_def_property_int_funcs(prop, NULL, "rna_Mask_end_frame_set", NULL);
1148   RNA_def_property_range(prop, MINFRAME, MAXFRAME);
1149   RNA_def_property_ui_text(prop, "End Frame", "Final frame of the mask (used for sequencer)");
1150   RNA_def_property_update(prop, NC_MASK | ND_DRAW, NULL);
1151
1152   /* pointers */
1153   rna_def_animdata_common(srna);
1154 }
1155
1156 void RNA_def_mask(BlenderRNA *brna)
1157 {
1158   rna_def_maskParent(brna);
1159   rna_def_mask(brna);
1160 }
1161
1162 #endif