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
23 #include "BLI_math.h"
24
25 #include "DNA_brush_types.h"
26 #include "DNA_gpencil_types.h"
27 #include "DNA_meshdata_types.h"
28 #include "DNA_object_types.h"
29 #include "DNA_scene_types.h"
30
31 #include "MEM_guardedalloc.h"
32
33 #include "BLI_utildefines.h"
34
35 #include "BLT_translation.h"
36
37 #include "RNA_access.h"
38 #include "RNA_define.h"
39 #include "RNA_enum_types.h"
40
41 #include "rna_internal.h"
42
43 #include "WM_types.h"
44
45 /* parent type */
46 static const EnumPropertyItem parent_type_items[] = {
47 {PAROBJECT, "OBJECT", 0, "Object", "The layer is parented to an object"},
48 {PARSKEL, "ARMATURE", 0, "Armature", ""},
49 {PARBONE, "BONE", 0, "Bone", "The layer is parented to a bone"},
50 {0, NULL, 0, NULL, NULL},
51 };
52
53 #ifndef RNA_RUNTIME
54 static EnumPropertyItem rna_enum_gpencil_stroke_depth_order_items[] = {
55 {GP_DRAWMODE_2D,
56 "2D",
57 0,
58 "2D Layers",
59 "Display strokes using grease pencil layers to define order"},
60 {GP_DRAWMODE_3D, "3D", 0, "3D Location", "Display strokes using real 3D position in 3D space"},
61 {0, NULL, 0, NULL, NULL},
62 };
63
64 static EnumPropertyItem rna_enum_gpencil_onion_modes_items[] = {
65 {GP_ONION_MODE_ABSOLUTE,
66 "ABSOLUTE",
67 0,
68 "Frames",
69 "Frames in absolute range of the scene frame"},
70 {GP_ONION_MODE_RELATIVE,
71 "RELATIVE",
72 0,
73 "Keyframes",
74 "Frames in relative range of the Grease Pencil keyframes"},
75 {GP_ONION_MODE_SELECTED, "SELECTED", 0, "Selected", "Only selected keyframes"},
76 {0, NULL, 0, NULL, NULL},
77 };
78
79 static const EnumPropertyItem rna_enum_keyframe_type_items[] = {
80 {BEZT_KEYTYPE_KEYFRAME,
81 "KEYFRAME",
82 ICON_KEYTYPE_KEYFRAME_VEC,
83 "Keyframe",
84 "Normal keyframe - e.g. for key poses"},
85 {BEZT_KEYTYPE_BREAKDOWN,
86 "BREAKDOWN",
87 ICON_KEYTYPE_BREAKDOWN_VEC,
88 "Breakdown",
89 "A breakdown pose - e.g. for transitions between key poses"},
90 {BEZT_KEYTYPE_MOVEHOLD,
91 "MOVING_HOLD",
92 ICON_KEYTYPE_MOVING_HOLD_VEC,
93 "Moving Hold",
94 "A keyframe that is part of a moving hold"},
95 {BEZT_KEYTYPE_EXTREME,
96 "EXTREME",
97 ICON_KEYTYPE_EXTREME_VEC,
98 "Extreme",
99 "An 'extreme' pose, or some other purpose as needed"},
100 {BEZT_KEYTYPE_JITTER,
101 "JITTER",
102 ICON_KEYTYPE_JITTER_VEC,
103 "Jitter",
104 "A filler or baked keyframe for keying on ones, or some other purpose as needed"},
105 {0, NULL, 0, NULL, NULL},
106 };
107
108 static const EnumPropertyItem rna_enum_onion_keyframe_type_items[] = {
109 {-1, "ALL", 0, "All", "Include all Keyframe types"},
110 {BEZT_KEYTYPE_KEYFRAME,
111 "KEYFRAME",
112 ICON_KEYTYPE_KEYFRAME_VEC,
113 "Keyframe",
114 "Normal keyframe - e.g. for key poses"},
115 {BEZT_KEYTYPE_BREAKDOWN,
116 "BREAKDOWN",
117 ICON_KEYTYPE_BREAKDOWN_VEC,
118 "Breakdown",
119 "A breakdown pose - e.g. for transitions between key poses"},
120 {BEZT_KEYTYPE_MOVEHOLD,
121 "MOVING_HOLD",
122 ICON_KEYTYPE_MOVING_HOLD_VEC,
123 "Moving Hold",
124 "A keyframe that is part of a moving hold"},
125 {BEZT_KEYTYPE_EXTREME,
126 "EXTREME",
127 ICON_KEYTYPE_EXTREME_VEC,
128 "Extreme",
129 "An 'extreme' pose, or some other purpose as needed"},
130 {BEZT_KEYTYPE_JITTER,
131 "JITTER",
132 ICON_KEYTYPE_JITTER_VEC,
133 "Jitter",
134 "A filler or baked keyframe for keying on ones, or some other purpose as needed"},
135 {0, NULL, 0, NULL, NULL},
136 };
137
138 static const EnumPropertyItem rna_enum_gplayer_move_type_items[] = {
139 {-1, "UP", 0, "Up", ""},
140 {1, "DOWN", 0, "Down", ""},
141 {0, NULL, 0, NULL, NULL},
142 };
143
144 static const EnumPropertyItem rna_enum_layer_blend_modes_items[] = {
145 {eGplBlendMode_Regular, "REGULAR", 0, "Regular", ""},
146 {eGplBlendMode_HardLight, "HARDLIGHT", 0, "Hard Light", ""},
147 {eGplBlendMode_Add, "ADD", 0, "Add", ""},
148 {eGplBlendMode_Subtract, "SUBTRACT", 0, "Subtract", ""},
149 {eGplBlendMode_Multiply, "MULTIPLY", 0, "Multiply", ""},
150 {eGplBlendMode_Divide, "DIVIDE", 0, "Divide", ""},
151 {0, NULL, 0, NULL, NULL}};
152
153 static const EnumPropertyItem rna_enum_gpencil_caps_modes_items[] = {
154 {GP_STROKE_CAP_ROUND, "ROUND", 0, "Rounded", ""},
155 {GP_STROKE_CAP_FLAT, "FLAT", 0, "Flat", ""},
156 {0, NULL, 0, NULL, NULL},
157 };
158 #endif
159
160 #ifdef RNA_RUNTIME
161
162 # include "BLI_ghash.h"
163 # include "BLI_string_utils.h"
164
165 # include "WM_api.h"
166
167 # include "BKE_action.h"
168 # include "BKE_animsys.h"
169 # include "BKE_gpencil.h"
170 # include "BKE_gpencil_geom.h"
171 # include "BKE_icons.h"
172
173 # include "DEG_depsgraph.h"
174 # include "DEG_depsgraph_build.h"
175
rna_GPencil_update(Main * UNUSED (bmain),Scene * UNUSED (scene),PointerRNA * ptr)176 static void rna_GPencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
177 {
178 DEG_id_tag_update(ptr->owner_id, ID_RECALC_GEOMETRY);
179 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
180 }
181
rna_GPencil_dependency_update(Main * bmain,Scene * UNUSED (scene),PointerRNA * ptr)182 static void rna_GPencil_dependency_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
183 {
184 DEG_id_tag_update(ptr->owner_id, ID_RECALC_TRANSFORM);
185 DEG_relations_tag_update(bmain);
186 WM_main_add_notifier(NC_OBJECT | ND_PARENT, ptr->owner_id);
187
188 DEG_id_tag_update(ptr->owner_id, ID_RECALC_GEOMETRY);
189 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
190 }
191
rna_GPencil_uv_update(Main * UNUSED (bmain),Scene * UNUSED (scene),PointerRNA * ptr)192 static void rna_GPencil_uv_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
193 {
194 /* Force to recalc the UVs. */
195 bGPDstroke *gps = (bGPDstroke *)ptr->data;
196
197 /* Calc geometry data. */
198 BKE_gpencil_stroke_geometry_update(gps);
199
200 DEG_id_tag_update(ptr->owner_id, ID_RECALC_GEOMETRY);
201 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
202 }
203
rna_GPencil_autolock(Main * bmain,Scene * scene,PointerRNA * ptr)204 static void rna_GPencil_autolock(Main *bmain, Scene *scene, PointerRNA *ptr)
205 {
206 bGPdata *gpd = (bGPdata *)ptr->owner_id;
207 BKE_gpencil_layer_autolock_set(gpd, true);
208
209 /* standard update */
210 rna_GPencil_update(bmain, scene, ptr);
211 }
212
rna_GPencil_editmode_update(Main * UNUSED (bmain),Scene * UNUSED (scene),PointerRNA * ptr)213 static void rna_GPencil_editmode_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
214 {
215 bGPdata *gpd = (bGPdata *)ptr->owner_id;
216 DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
217
218 /* Notify all places where GPencil data lives that the editing state is different */
219 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
220 WM_main_add_notifier(NC_SCENE | ND_MODE | NC_MOVIECLIP, NULL);
221 }
222
223 /* Poll Callback to filter GP Datablocks to only show those for Annotations */
rna_GPencil_datablocks_annotations_poll(PointerRNA * UNUSED (ptr),const PointerRNA value)224 bool rna_GPencil_datablocks_annotations_poll(PointerRNA *UNUSED(ptr), const PointerRNA value)
225 {
226 bGPdata *gpd = value.data;
227 return (gpd->flag & GP_DATA_ANNOTATIONS) != 0;
228 }
229
230 /* Poll Callback to filter GP Datablocks to only show those for GP Objects */
rna_GPencil_datablocks_obdata_poll(PointerRNA * UNUSED (ptr),const PointerRNA value)231 bool rna_GPencil_datablocks_obdata_poll(PointerRNA *UNUSED(ptr), const PointerRNA value)
232 {
233 bGPdata *gpd = value.data;
234 return (gpd->flag & GP_DATA_ANNOTATIONS) == 0;
235 }
236
rna_GPencilLayer_path(PointerRNA * ptr)237 static char *rna_GPencilLayer_path(PointerRNA *ptr)
238 {
239 bGPDlayer *gpl = (bGPDlayer *)ptr->data;
240 char name_esc[sizeof(gpl->info) * 2];
241
242 BLI_strescape(name_esc, gpl->info, sizeof(name_esc));
243
244 return BLI_sprintfN("layers[\"%s\"]", name_esc);
245 }
246
rna_GPencilLayer_active_frame_editable(PointerRNA * ptr,const char ** UNUSED (r_info))247 static int rna_GPencilLayer_active_frame_editable(PointerRNA *ptr, const char **UNUSED(r_info))
248 {
249 bGPDlayer *gpl = (bGPDlayer *)ptr->data;
250
251 /* surely there must be other criteria too... */
252 if (gpl->flag & GP_LAYER_LOCKED) {
253 return 0;
254 }
255 else {
256 return PROP_EDITABLE;
257 }
258 }
259
260 /* set parent */
set_parent(bGPDlayer * gpl,Object * par,const int type,const char * substr)261 static void set_parent(bGPDlayer *gpl, Object *par, const int type, const char *substr)
262 {
263 if (type == PAROBJECT) {
264 invert_m4_m4(gpl->inverse, par->obmat);
265 gpl->parent = par;
266 gpl->partype |= PAROBJECT;
267 gpl->parsubstr[0] = 0;
268 }
269 else if (type == PARSKEL) {
270 invert_m4_m4(gpl->inverse, par->obmat);
271 gpl->parent = par;
272 gpl->partype |= PARSKEL;
273 gpl->parsubstr[0] = 0;
274 }
275 else if (type == PARBONE) {
276 bPoseChannel *pchan = BKE_pose_channel_find_name(par->pose, substr);
277 if (pchan) {
278 float tmp_mat[4][4];
279 mul_m4_m4m4(tmp_mat, par->obmat, pchan->pose_mat);
280
281 invert_m4_m4(gpl->inverse, tmp_mat);
282 gpl->parent = par;
283 gpl->partype |= PARBONE;
284 BLI_strncpy(gpl->parsubstr, substr, sizeof(gpl->parsubstr));
285 }
286 }
287 }
288
289 /* set parent object and inverse matrix */
rna_GPencilLayer_parent_set(PointerRNA * ptr,PointerRNA value,struct ReportList * UNUSED (reports))290 static void rna_GPencilLayer_parent_set(PointerRNA *ptr,
291 PointerRNA value,
292 struct ReportList *UNUSED(reports))
293 {
294 bGPDlayer *gpl = (bGPDlayer *)ptr->data;
295 Object *par = (Object *)value.data;
296
297 if (par != NULL) {
298 set_parent(gpl, par, gpl->partype, gpl->parsubstr);
299 }
300 else {
301 /* clear parent */
302 gpl->parent = NULL;
303 }
304 }
305
306 /* set parent type */
rna_GPencilLayer_parent_type_set(PointerRNA * ptr,int value)307 static void rna_GPencilLayer_parent_type_set(PointerRNA *ptr, int value)
308 {
309 bGPDlayer *gpl = (bGPDlayer *)ptr->data;
310 Object *par = gpl->parent;
311 gpl->partype = value;
312
313 if (par != NULL) {
314 set_parent(gpl, par, value, gpl->parsubstr);
315 }
316 }
317
318 /* set parent bone */
rna_GPencilLayer_parent_bone_set(PointerRNA * ptr,const char * value)319 static void rna_GPencilLayer_parent_bone_set(PointerRNA *ptr, const char *value)
320 {
321 bGPDlayer *gpl = (bGPDlayer *)ptr->data;
322
323 Object *par = gpl->parent;
324 gpl->partype = PARBONE;
325
326 if (par != NULL) {
327 set_parent(gpl, par, gpl->partype, value);
328 }
329 }
330
rna_GPencilLayerMask_path(PointerRNA * ptr)331 static char *rna_GPencilLayerMask_path(PointerRNA *ptr)
332 {
333 bGPdata *gpd = (bGPdata *)ptr->owner_id;
334 bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
335 bGPDlayer_Mask *mask = (bGPDlayer_Mask *)ptr->data;
336
337 char name_layer[sizeof(gpl->info) * 2];
338 char name_mask[sizeof(mask->name) * 2];
339
340 BLI_strescape(name_layer, gpl->info, sizeof(name_layer));
341 BLI_strescape(name_mask, mask->name, sizeof(name_mask));
342
343 return BLI_sprintfN("layers[\"%s\"].mask_layers[\"%s\"]", name_layer, name_mask);
344 }
345
rna_GPencil_active_mask_index_get(PointerRNA * ptr)346 static int rna_GPencil_active_mask_index_get(PointerRNA *ptr)
347 {
348 bGPDlayer *gpl = (bGPDlayer *)ptr->data;
349 return gpl->act_mask - 1;
350 }
351
rna_GPencil_active_mask_index_set(PointerRNA * ptr,int value)352 static void rna_GPencil_active_mask_index_set(PointerRNA *ptr, int value)
353 {
354 bGPDlayer *gpl = (bGPDlayer *)ptr->data;
355 gpl->act_mask = value + 1;
356 }
357
rna_GPencil_active_mask_index_range(PointerRNA * ptr,int * min,int * max,int * UNUSED (softmin),int * UNUSED (softmax))358 static void rna_GPencil_active_mask_index_range(
359 PointerRNA *ptr, int *min, int *max, int *UNUSED(softmin), int *UNUSED(softmax))
360 {
361 bGPDlayer *gpl = (bGPDlayer *)ptr->data;
362
363 *min = 0;
364 *max = max_ii(0, BLI_listbase_count(&gpl->mask_layers) - 1);
365 }
366
367 /* parent types enum */
rna_Object_parent_type_itemf(bContext * UNUSED (C),PointerRNA * ptr,PropertyRNA * UNUSED (prop),bool * r_free)368 static const EnumPropertyItem *rna_Object_parent_type_itemf(bContext *UNUSED(C),
369 PointerRNA *ptr,
370 PropertyRNA *UNUSED(prop),
371 bool *r_free)
372 {
373 bGPDlayer *gpl = (bGPDlayer *)ptr->data;
374 EnumPropertyItem *item = NULL;
375 int totitem = 0;
376
377 RNA_enum_items_add_value(&item, &totitem, parent_type_items, PAROBJECT);
378
379 if (gpl->parent) {
380 Object *par = gpl->parent;
381
382 if (par->type == OB_ARMATURE) {
383 /* special hack: prevents this being overridden */
384 RNA_enum_items_add_value(&item, &totitem, &parent_type_items[1], PARSKEL);
385 RNA_enum_items_add_value(&item, &totitem, parent_type_items, PARBONE);
386 }
387 }
388
389 RNA_enum_item_end(&item, &totitem);
390 *r_free = true;
391
392 return item;
393 }
394
rna_GPencilLayer_is_parented_get(PointerRNA * ptr)395 static bool rna_GPencilLayer_is_parented_get(PointerRNA *ptr)
396 {
397 bGPDlayer *gpl = (bGPDlayer *)ptr->data;
398 return (gpl->parent != NULL);
399 }
400
rna_GPencil_active_layer_get(PointerRNA * ptr)401 static PointerRNA rna_GPencil_active_layer_get(PointerRNA *ptr)
402 {
403 bGPdata *gpd = (bGPdata *)ptr->owner_id;
404
405 if (GS(gpd->id.name) == ID_GD) { /* why would this ever be not GD */
406 bGPDlayer *gl;
407
408 for (gl = gpd->layers.first; gl; gl = gl->next) {
409 if (gl->flag & GP_LAYER_ACTIVE) {
410 break;
411 }
412 }
413
414 if (gl) {
415 return rna_pointer_inherit_refine(ptr, &RNA_GPencilLayer, gl);
416 }
417 }
418
419 return rna_pointer_inherit_refine(ptr, NULL, NULL);
420 }
421
rna_GPencil_active_layer_set(PointerRNA * ptr,PointerRNA value,struct ReportList * UNUSED (reports))422 static void rna_GPencil_active_layer_set(PointerRNA *ptr,
423 PointerRNA value,
424 struct ReportList *UNUSED(reports))
425 {
426 bGPdata *gpd = (bGPdata *)ptr->owner_id;
427
428 /* Don't allow setting active layer to NULL if layers exist
429 * as this breaks various tools. Tools should be used instead
430 * if it's necessary to remove layers
431 */
432 if (value.data == NULL) {
433 printf("%s: Setting active layer to None is not allowed\n", __func__);
434 return;
435 }
436
437 if (GS(gpd->id.name) == ID_GD) { /* why would this ever be not GD */
438 bGPDlayer *gl;
439
440 for (gl = gpd->layers.first; gl; gl = gl->next) {
441 if (gl == value.data) {
442 gl->flag |= GP_LAYER_ACTIVE;
443 }
444 else {
445 gl->flag &= ~GP_LAYER_ACTIVE;
446 }
447 }
448
449 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
450 }
451 }
452
rna_GPencil_active_layer_index_get(PointerRNA * ptr)453 static int rna_GPencil_active_layer_index_get(PointerRNA *ptr)
454 {
455 bGPdata *gpd = (bGPdata *)ptr->owner_id;
456 bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
457
458 return BLI_findindex(&gpd->layers, gpl);
459 }
460
rna_GPencil_active_layer_index_set(PointerRNA * ptr,int value)461 static void rna_GPencil_active_layer_index_set(PointerRNA *ptr, int value)
462 {
463 bGPdata *gpd = (bGPdata *)ptr->owner_id;
464 bGPDlayer *gpl = BLI_findlink(&gpd->layers, value);
465
466 BKE_gpencil_layer_active_set(gpd, gpl);
467
468 /* Now do standard updates... */
469 DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY);
470 WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
471 }
472
rna_GPencil_active_layer_index_range(PointerRNA * ptr,int * min,int * max,int * softmin,int * softmax)473 static void rna_GPencil_active_layer_index_range(
474 PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax)
475 {
476 bGPdata *gpd = (bGPdata *)ptr->owner_id;
477
478 *min = 0;
479 *max = max_ii(0, BLI_listbase_count(&gpd->layers) - 1);
480
481 *softmin = *min;
482 *softmax = *max;
483 }
484
rna_GPencil_active_layer_itemf(bContext * C,PointerRNA * ptr,PropertyRNA * UNUSED (prop),bool * r_free)485 static const EnumPropertyItem *rna_GPencil_active_layer_itemf(bContext *C,
486 PointerRNA *ptr,
487 PropertyRNA *UNUSED(prop),
488 bool *r_free)
489 {
490 bGPdata *gpd = (bGPdata *)ptr->owner_id;
491 bGPDlayer *gpl;
492 EnumPropertyItem *item = NULL, item_tmp = {0};
493 int totitem = 0;
494 int i = 0;
495
496 if (ELEM(NULL, C, gpd)) {
497 return DummyRNA_NULL_items;
498 }
499
500 /* Existing layers */
501 for (gpl = gpd->layers.first, i = 0; gpl; gpl = gpl->next, i++) {
502 item_tmp.identifier = gpl->info;
503 item_tmp.name = gpl->info;
504 item_tmp.value = i;
505
506 item_tmp.icon = (gpd->flag & GP_DATA_ANNOTATIONS) ? BKE_icon_gplayer_color_ensure(gpl) :
507 ICON_GREASEPENCIL;
508
509 RNA_enum_item_add(&item, &totitem, &item_tmp);
510 }
511
512 RNA_enum_item_end(&item, &totitem);
513 *r_free = true;
514
515 return item;
516 }
517
rna_GPencilLayer_info_set(PointerRNA * ptr,const char * value)518 static void rna_GPencilLayer_info_set(PointerRNA *ptr, const char *value)
519 {
520 bGPdata *gpd = (bGPdata *)ptr->owner_id;
521 bGPDlayer *gpl = ptr->data;
522
523 char oldname[128] = "";
524 BLI_strncpy(oldname, gpl->info, sizeof(oldname));
525
526 /* copy the new name into the name slot */
527 BLI_strncpy_utf8(gpl->info, value, sizeof(gpl->info));
528
529 BLI_uniquename(
530 &gpd->layers, gpl, DATA_("GP_Layer"), '.', offsetof(bGPDlayer, info), sizeof(gpl->info));
531
532 /* now fix animation paths */
533 BKE_animdata_fix_paths_rename_all(&gpd->id, "layers", oldname, gpl->info);
534
535 /* Fix mask layers. */
536 LISTBASE_FOREACH (bGPDlayer *, gpl_, &gpd->layers) {
537 LISTBASE_FOREACH (bGPDlayer_Mask *, mask, &gpl_->mask_layers) {
538 if (STREQ(mask->name, oldname)) {
539 BLI_strncpy(mask->name, gpl->info, sizeof(mask->name));
540 }
541 }
542 }
543 }
544
rna_GPencilLayer_mask_info_set(PointerRNA * ptr,const char * value)545 static void rna_GPencilLayer_mask_info_set(PointerRNA *ptr, const char *value)
546 {
547 bGPdata *gpd = (bGPdata *)ptr->owner_id;
548 bGPDlayer_Mask *mask = ptr->data;
549 char oldname[128] = "";
550 BLI_strncpy(oldname, mask->name, sizeof(oldname));
551
552 /* Really is changing the layer name. */
553 bGPDlayer *gpl = BKE_gpencil_layer_named_get(gpd, oldname);
554 if (gpl) {
555 /* copy the new name into the name slot */
556 BLI_strncpy_utf8(gpl->info, value, sizeof(gpl->info));
557
558 BLI_uniquename(
559 &gpd->layers, gpl, DATA_("GP_Layer"), '.', offsetof(bGPDlayer, info), sizeof(gpl->info));
560
561 /* now fix animation paths */
562 BKE_animdata_fix_paths_rename_all(&gpd->id, "layers", oldname, gpl->info);
563
564 /* Fix mask layers. */
565 LISTBASE_FOREACH (bGPDlayer *, gpl_, &gpd->layers) {
566 LISTBASE_FOREACH (bGPDlayer_Mask *, mask_, &gpl_->mask_layers) {
567 if (STREQ(mask_->name, oldname)) {
568 BLI_strncpy(mask_->name, gpl->info, sizeof(mask_->name));
569 }
570 }
571 }
572 }
573 }
574
rna_GPencil_stroke_point_find_stroke(const bGPdata * gpd,const bGPDspoint * pt,bGPDlayer ** r_gpl,bGPDframe ** r_gpf)575 static bGPDstroke *rna_GPencil_stroke_point_find_stroke(const bGPdata *gpd,
576 const bGPDspoint *pt,
577 bGPDlayer **r_gpl,
578 bGPDframe **r_gpf)
579 {
580 bGPDlayer *gpl;
581 bGPDstroke *gps;
582
583 /* sanity checks */
584 if (ELEM(NULL, gpd, pt)) {
585 return NULL;
586 }
587
588 if (r_gpl) {
589 *r_gpl = NULL;
590 }
591 if (r_gpf) {
592 *r_gpf = NULL;
593 }
594
595 /* there's no faster alternative than just looping over everything... */
596 for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
597 if (gpl->actframe) {
598 for (gps = gpl->actframe->strokes.first; gps; gps = gps->next) {
599 if ((pt >= gps->points) && (pt < &gps->points[gps->totpoints])) {
600 /* found it */
601 if (r_gpl) {
602 *r_gpl = gpl;
603 }
604 if (r_gpf) {
605 *r_gpf = gpl->actframe;
606 }
607
608 return gps;
609 }
610 }
611 }
612 }
613
614 /* didn't find it */
615 return NULL;
616 }
617
rna_GPencil_stroke_point_select_set(PointerRNA * ptr,const bool value)618 static void rna_GPencil_stroke_point_select_set(PointerRNA *ptr, const bool value)
619 {
620 bGPdata *gpd = (bGPdata *)ptr->owner_id;
621 bGPDspoint *pt = ptr->data;
622 bGPDstroke *gps = NULL;
623
624 /* Ensure that corresponding stroke is set
625 * - Since we don't have direct access, we're going to have to search
626 * - We don't apply selection value unless we can find the corresponding
627 * stroke, so that they don't get out of sync
628 */
629 gps = rna_GPencil_stroke_point_find_stroke(gpd, pt, NULL, NULL);
630 if (gps) {
631 /* Set the new selection state for the point */
632 if (value) {
633 pt->flag |= GP_SPOINT_SELECT;
634 }
635 else {
636 pt->flag &= ~GP_SPOINT_SELECT;
637 }
638
639 /* Check if the stroke should be selected or not... */
640 BKE_gpencil_stroke_sync_selection(gps);
641 }
642 }
643
rna_GPencil_stroke_point_add(ID * id,bGPDstroke * stroke,int count,float pressure,float strength)644 static void rna_GPencil_stroke_point_add(
645 ID *id, bGPDstroke *stroke, int count, float pressure, float strength)
646 {
647 bGPdata *gpd = (bGPdata *)id;
648
649 if (count > 0) {
650 /* create space at the end of the array for extra points */
651 stroke->points = MEM_recallocN_id(
652 stroke->points, sizeof(bGPDspoint) * (stroke->totpoints + count), "gp_stroke_points");
653 stroke->dvert = MEM_recallocN_id(
654 stroke->dvert, sizeof(MDeformVert) * (stroke->totpoints + count), "gp_stroke_weight");
655
656 /* init the pressure and strength values so that old scripts won't need to
657 * be modified to give these initial values...
658 */
659 for (int i = 0; i < count; i++) {
660 bGPDspoint *pt = stroke->points + (stroke->totpoints + i);
661 MDeformVert *dvert = stroke->dvert + (stroke->totpoints + i);
662 pt->pressure = pressure;
663 pt->strength = strength;
664
665 dvert->totweight = 0;
666 dvert->dw = NULL;
667 }
668
669 stroke->totpoints += count;
670
671 /* Calc geometry data. */
672 BKE_gpencil_stroke_geometry_update(stroke);
673
674 DEG_id_tag_update(&gpd->id,
675 ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
676
677 WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
678 }
679 }
680
rna_GPencil_stroke_point_pop(ID * id,bGPDstroke * stroke,ReportList * reports,int index)681 static void rna_GPencil_stroke_point_pop(ID *id,
682 bGPDstroke *stroke,
683 ReportList *reports,
684 int index)
685 {
686 bGPdata *gpd = (bGPdata *)id;
687 bGPDspoint *pt_tmp = stroke->points;
688 MDeformVert *pt_dvert = stroke->dvert;
689
690 /* python style negative indexing */
691 if (index < 0) {
692 index += stroke->totpoints;
693 }
694
695 if (stroke->totpoints <= index || index < 0) {
696 BKE_report(reports, RPT_ERROR, "GPencilStrokePoints.pop: index out of range");
697 return;
698 }
699
700 stroke->totpoints--;
701
702 stroke->points = MEM_callocN(sizeof(bGPDspoint) * stroke->totpoints, "gp_stroke_points");
703 if (pt_dvert != NULL) {
704 stroke->dvert = MEM_callocN(sizeof(MDeformVert) * stroke->totpoints, "gp_stroke_weights");
705 }
706
707 if (index > 0) {
708 memcpy(stroke->points, pt_tmp, sizeof(bGPDspoint) * index);
709 /* verify weight data is available */
710 if (pt_dvert != NULL) {
711 memcpy(stroke->dvert, pt_dvert, sizeof(MDeformVert) * index);
712 }
713 }
714
715 if (index < stroke->totpoints) {
716 memcpy(&stroke->points[index],
717 &pt_tmp[index + 1],
718 sizeof(bGPDspoint) * (stroke->totpoints - index));
719 if (pt_dvert != NULL) {
720 memcpy(&stroke->dvert[index],
721 &pt_dvert[index + 1],
722 sizeof(MDeformVert) * (stroke->totpoints - index));
723 }
724 }
725
726 /* free temp buffer */
727 MEM_freeN(pt_tmp);
728 if (pt_dvert != NULL) {
729 MEM_freeN(pt_dvert);
730 }
731
732 /* Calc geometry data. */
733 BKE_gpencil_stroke_geometry_update(stroke);
734
735 DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
736
737 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
738 }
739
rna_GPencil_stroke_new(bGPDframe * frame)740 static bGPDstroke *rna_GPencil_stroke_new(bGPDframe *frame)
741 {
742 bGPDstroke *stroke = BKE_gpencil_stroke_new(0, 0, 1.0f);
743 BLI_addtail(&frame->strokes, stroke);
744
745 return stroke;
746 }
747
rna_GPencil_stroke_remove(ID * id,bGPDframe * frame,ReportList * reports,PointerRNA * stroke_ptr)748 static void rna_GPencil_stroke_remove(ID *id,
749 bGPDframe *frame,
750 ReportList *reports,
751 PointerRNA *stroke_ptr)
752 {
753 bGPdata *gpd = (bGPdata *)id;
754
755 bGPDstroke *stroke = stroke_ptr->data;
756 if (BLI_findindex(&frame->strokes, stroke) == -1) {
757 BKE_report(reports, RPT_ERROR, "Stroke not found in grease pencil frame");
758 return;
759 }
760
761 BLI_freelinkN(&frame->strokes, stroke);
762 RNA_POINTER_INVALIDATE(stroke_ptr);
763
764 DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
765 WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
766 }
767
rna_GPencil_stroke_close(ID * id,bGPDframe * frame,ReportList * reports,PointerRNA * stroke_ptr)768 static void rna_GPencil_stroke_close(ID *id,
769 bGPDframe *frame,
770 ReportList *reports,
771 PointerRNA *stroke_ptr)
772 {
773 bGPdata *gpd = (bGPdata *)id;
774 bGPDstroke *stroke = stroke_ptr->data;
775 if (BLI_findindex(&frame->strokes, stroke) == -1) {
776 BKE_report(reports, RPT_ERROR, "Stroke not found in grease pencil frame");
777 return;
778 }
779
780 BKE_gpencil_stroke_close(stroke);
781
782 DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_COPY_ON_WRITE);
783 WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
784 }
785
rna_GPencil_stroke_select_set(PointerRNA * ptr,const bool value)786 static void rna_GPencil_stroke_select_set(PointerRNA *ptr, const bool value)
787 {
788 bGPDstroke *gps = ptr->data;
789 bGPDspoint *pt;
790 int i;
791
792 /* set new value */
793 if (value) {
794 gps->flag |= GP_STROKE_SELECT;
795 }
796 else {
797 gps->flag &= ~GP_STROKE_SELECT;
798 }
799
800 /* ensure that the stroke's points are selected in the same way */
801 for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
802 if (value) {
803 pt->flag |= GP_SPOINT_SELECT;
804 }
805 else {
806 pt->flag &= ~GP_SPOINT_SELECT;
807 }
808 }
809 }
810
rna_GPencil_frame_new(bGPDlayer * layer,ReportList * reports,int frame_number,bool active)811 static bGPDframe *rna_GPencil_frame_new(bGPDlayer *layer,
812 ReportList *reports,
813 int frame_number,
814 bool active)
815 {
816 bGPDframe *frame;
817
818 if (BKE_gpencil_layer_frame_find(layer, frame_number)) {
819 BKE_reportf(reports, RPT_ERROR, "Frame already exists on this frame number %d", frame_number);
820 return NULL;
821 }
822
823 frame = BKE_gpencil_frame_addnew(layer, frame_number);
824 if (active) {
825 layer->actframe = BKE_gpencil_layer_frame_get(layer, frame_number, GP_GETFRAME_USE_PREV);
826 }
827 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
828
829 return frame;
830 }
831
rna_GPencil_frame_remove(bGPDlayer * layer,ReportList * reports,PointerRNA * frame_ptr)832 static void rna_GPencil_frame_remove(bGPDlayer *layer, ReportList *reports, PointerRNA *frame_ptr)
833 {
834 bGPDframe *frame = frame_ptr->data;
835 if (BLI_findindex(&layer->frames, frame) == -1) {
836 BKE_report(reports, RPT_ERROR, "Frame not found in grease pencil layer");
837 return;
838 }
839
840 BKE_gpencil_layer_frame_delete(layer, frame);
841 RNA_POINTER_INVALIDATE(frame_ptr);
842
843 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
844 }
845
rna_GPencil_frame_copy(bGPDlayer * layer,bGPDframe * src)846 static bGPDframe *rna_GPencil_frame_copy(bGPDlayer *layer, bGPDframe *src)
847 {
848 bGPDframe *frame = BKE_gpencil_frame_duplicate(src);
849
850 while (BKE_gpencil_layer_frame_find(layer, frame->framenum)) {
851 frame->framenum++;
852 }
853
854 BLI_addtail(&layer->frames, frame);
855
856 WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
857
858 return frame;
859 }
860
rna_GPencil_layer_new(bGPdata * gpd,const char * name,bool setactive)861 static bGPDlayer *rna_GPencil_layer_new(bGPdata *gpd, const char *name, bool setactive)
862 {
863 bGPDlayer *gpl = BKE_gpencil_layer_addnew(gpd, name, setactive != 0);
864
865 WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
866
867 return gpl;
868 }
869
rna_GPencil_layer_remove(bGPdata * gpd,ReportList * reports,PointerRNA * layer_ptr)870 static void rna_GPencil_layer_remove(bGPdata *gpd, ReportList *reports, PointerRNA *layer_ptr)
871 {
872 bGPDlayer *layer = layer_ptr->data;
873 if (BLI_findindex(&gpd->layers, layer) == -1) {
874 BKE_report(reports, RPT_ERROR, "Layer not found in grease pencil data");
875 return;
876 }
877
878 BKE_gpencil_layer_delete(gpd, layer);
879 RNA_POINTER_INVALIDATE(layer_ptr);
880
881 WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
882 }
883
rna_GPencil_layer_move(bGPdata * gpd,ReportList * reports,PointerRNA * layer_ptr,int type)884 static void rna_GPencil_layer_move(bGPdata *gpd,
885 ReportList *reports,
886 PointerRNA *layer_ptr,
887 int type)
888 {
889 bGPDlayer *gpl = layer_ptr->data;
890 if (BLI_findindex(&gpd->layers, gpl) == -1) {
891 BKE_report(reports, RPT_ERROR, "Layer not found in grease pencil data");
892 return;
893 }
894
895 BLI_assert(ELEM(type, -1, 0, 1)); /* we use value below */
896
897 const int direction = type * -1;
898
899 if (BLI_listbase_link_move(&gpd->layers, gpl, direction)) {
900 DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
901 }
902
903 WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
904 }
905
rna_GPencil_layer_mask_add(bGPDlayer * gpl,PointerRNA * layer_ptr)906 static void rna_GPencil_layer_mask_add(bGPDlayer *gpl, PointerRNA *layer_ptr)
907 {
908 bGPDlayer *gpl_mask = layer_ptr->data;
909
910 BKE_gpencil_layer_mask_add(gpl, gpl_mask->info);
911
912 WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
913 }
914
rna_GPencil_layer_mask_remove(bGPDlayer * gpl,ReportList * reports,PointerRNA * mask_ptr)915 static void rna_GPencil_layer_mask_remove(bGPDlayer *gpl,
916 ReportList *reports,
917 PointerRNA *mask_ptr)
918 {
919 bGPDlayer_Mask *mask = mask_ptr->data;
920 if (BLI_findindex(&gpl->mask_layers, mask) == -1) {
921 BKE_report(reports, RPT_ERROR, "Mask not found in mask list");
922 return;
923 }
924
925 BKE_gpencil_layer_mask_remove(gpl, mask);
926 RNA_POINTER_INVALIDATE(mask_ptr);
927
928 WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
929 }
930
rna_GPencil_frame_clear(bGPDframe * frame)931 static void rna_GPencil_frame_clear(bGPDframe *frame)
932 {
933 BKE_gpencil_free_strokes(frame);
934
935 WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
936 }
937
rna_GPencil_layer_clear(bGPDlayer * layer)938 static void rna_GPencil_layer_clear(bGPDlayer *layer)
939 {
940 BKE_gpencil_free_frames(layer);
941
942 WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
943 }
944
rna_GPencil_clear(bGPdata * gpd)945 static void rna_GPencil_clear(bGPdata *gpd)
946 {
947 BKE_gpencil_free_layers(&gpd->layers);
948
949 WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
950 }
951
rna_GpencilVertex_groups_begin(CollectionPropertyIterator * iter,PointerRNA * ptr)952 static void rna_GpencilVertex_groups_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
953 {
954 bGPDstroke *gps = ptr->data;
955
956 if (gps->dvert) {
957 MDeformVert *dvert = gps->dvert;
958
959 rna_iterator_array_begin(
960 iter, (void *)dvert->dw, sizeof(MDeformWeight), dvert->totweight, 0, NULL);
961 }
962 else {
963 rna_iterator_array_begin(iter, NULL, 0, 0, 0, NULL);
964 }
965 }
966
rna_GreasePencilGrid_path(PointerRNA * UNUSED (ptr))967 static char *rna_GreasePencilGrid_path(PointerRNA *UNUSED(ptr))
968 {
969 return BLI_strdup("grid");
970 }
971
972 #else
973
rna_def_gpencil_stroke_point(BlenderRNA * brna)974 static void rna_def_gpencil_stroke_point(BlenderRNA *brna)
975 {
976 StructRNA *srna;
977 PropertyRNA *prop;
978
979 srna = RNA_def_struct(brna, "GPencilStrokePoint", NULL);
980 RNA_def_struct_sdna(srna, "bGPDspoint");
981 RNA_def_struct_ui_text(
982 srna, "Grease Pencil Stroke Point", "Data point for freehand stroke curve");
983
984 prop = RNA_def_property(srna, "co", PROP_FLOAT, PROP_XYZ);
985 RNA_def_property_float_sdna(prop, NULL, "x");
986 RNA_def_property_array(prop, 3);
987 RNA_def_property_ui_text(prop, "Coordinates", "");
988 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
989
990 prop = RNA_def_property(srna, "pressure", PROP_FLOAT, PROP_FACTOR);
991 RNA_def_property_float_sdna(prop, NULL, "pressure");
992 RNA_def_property_range(prop, 0.0f, FLT_MAX);
993 RNA_def_property_ui_text(prop, "Pressure", "Pressure of tablet at point when drawing it");
994 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
995
996 prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_FACTOR);
997 RNA_def_property_float_sdna(prop, NULL, "strength");
998 RNA_def_property_range(prop, 0.0f, 1.0f);
999 RNA_def_property_ui_text(prop, "Strength", "Color intensity (alpha factor)");
1000 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1001
1002 prop = RNA_def_property(srna, "uv_factor", PROP_FLOAT, PROP_FACTOR);
1003 RNA_def_property_float_sdna(prop, NULL, "uv_fac");
1004 RNA_def_property_range(prop, 0.0f, 1.0f);
1005 RNA_def_property_ui_text(prop, "UV Factor", "Internal UV factor");
1006 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1007
1008 prop = RNA_def_property(srna, "uv_rotation", PROP_FLOAT, PROP_ANGLE);
1009 RNA_def_property_float_sdna(prop, NULL, "uv_rot");
1010 RNA_def_property_range(prop, -M_PI_2, M_PI_2);
1011 RNA_def_property_ui_text(prop, "UV Rotation", "Internal UV factor for dot mode");
1012 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1013
1014 prop = RNA_def_property(srna, "uv_fill", PROP_FLOAT, PROP_XYZ);
1015 RNA_def_property_float_sdna(prop, NULL, "uv_fill");
1016 RNA_def_property_array(prop, 2);
1017 RNA_def_property_ui_text(prop, "UV Fill", "Internal UV factor for filling");
1018 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1019
1020 prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
1021 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_SPOINT_SELECT);
1022 RNA_def_property_boolean_funcs(prop, NULL, "rna_GPencil_stroke_point_select_set");
1023 RNA_def_property_ui_text(prop, "Select", "Point is selected for viewport editing");
1024 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1025
1026 /* Vertex color. */
1027 prop = RNA_def_property(srna, "vertex_color", PROP_FLOAT, PROP_COLOR);
1028 RNA_def_property_float_sdna(prop, NULL, "vert_color");
1029 RNA_def_property_array(prop, 4);
1030 RNA_def_property_range(prop, 0.0f, 1.0f);
1031 RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1032 RNA_def_property_ui_text(
1033 prop, "Vertex Color", "Color used to mix with point color to get final color");
1034 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1035 }
1036
rna_def_gpencil_stroke_points_api(BlenderRNA * brna,PropertyRNA * cprop)1037 static void rna_def_gpencil_stroke_points_api(BlenderRNA *brna, PropertyRNA *cprop)
1038 {
1039 StructRNA *srna;
1040 FunctionRNA *func;
1041 PropertyRNA *parm;
1042
1043 RNA_def_property_srna(cprop, "GPencilStrokePoints");
1044 srna = RNA_def_struct(brna, "GPencilStrokePoints", NULL);
1045 RNA_def_struct_sdna(srna, "bGPDstroke");
1046 RNA_def_struct_ui_text(
1047 srna, "Grease Pencil Stroke Points", "Collection of grease pencil stroke points");
1048
1049 func = RNA_def_function(srna, "add", "rna_GPencil_stroke_point_add");
1050 RNA_def_function_ui_description(func, "Add a new grease pencil stroke point");
1051 RNA_def_function_flag(func, FUNC_USE_SELF_ID);
1052 parm = RNA_def_int(
1053 func, "count", 1, 0, INT_MAX, "Number", "Number of points to add to the stroke", 0, INT_MAX);
1054 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1055 RNA_def_float(func,
1056 "pressure",
1057 1.0f,
1058 0.0f,
1059 FLT_MAX,
1060 "Pressure",
1061 "Pressure for newly created points",
1062 0.0f,
1063 FLT_MAX);
1064 RNA_def_float(func,
1065 "strength",
1066 1.0f,
1067 0.0f,
1068 1.0f,
1069 "Strength",
1070 "Color intensity (alpha factor) for newly created points",
1071 0.0f,
1072 1.0f);
1073
1074 func = RNA_def_function(srna, "pop", "rna_GPencil_stroke_point_pop");
1075 RNA_def_function_ui_description(func, "Remove a grease pencil stroke point");
1076 RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
1077 RNA_def_int(func, "index", -1, INT_MIN, INT_MAX, "Index", "point index", INT_MIN, INT_MAX);
1078 }
1079
1080 /* This information is read only and it can be used by add-ons */
rna_def_gpencil_triangle(BlenderRNA * brna)1081 static void rna_def_gpencil_triangle(BlenderRNA *brna)
1082 {
1083 StructRNA *srna;
1084 PropertyRNA *prop;
1085
1086 srna = RNA_def_struct(brna, "GPencilTriangle", NULL);
1087 RNA_def_struct_sdna(srna, "bGPDtriangle");
1088 RNA_def_struct_ui_text(srna, "Triangle", "Triangulation data for Grease Pencil fills");
1089
1090 /* point v1 */
1091 prop = RNA_def_property(srna, "v1", PROP_INT, PROP_NONE);
1092 RNA_def_property_int_sdna(prop, NULL, "verts[0]");
1093 RNA_def_property_ui_text(prop, "v1", "First triangle vertex index");
1094 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1095
1096 /* point v2 */
1097 prop = RNA_def_property(srna, "v2", PROP_INT, PROP_NONE);
1098 RNA_def_property_int_sdna(prop, NULL, "verts[1]");
1099 RNA_def_property_ui_text(prop, "v2", "Second triangle vertex index");
1100 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1101
1102 /* point v3 */
1103 prop = RNA_def_property(srna, "v3", PROP_INT, PROP_NONE);
1104 RNA_def_property_int_sdna(prop, NULL, "verts[2]");
1105 RNA_def_property_ui_text(prop, "v3", "Third triangle vertex index");
1106 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1107 }
1108
rna_def_gpencil_mvert_group(BlenderRNA * brna)1109 static void rna_def_gpencil_mvert_group(BlenderRNA *brna)
1110 {
1111 StructRNA *srna;
1112 PropertyRNA *prop;
1113
1114 srna = RNA_def_struct(brna, "GpencilVertexGroupElement", NULL);
1115 RNA_def_struct_sdna(srna, "MDeformWeight");
1116 RNA_def_struct_ui_text(
1117 srna, "Vertex Group Element", "Weight value of a vertex in a vertex group");
1118 RNA_def_struct_ui_icon(srna, ICON_GROUP_VERTEX);
1119
1120 /* we can't point to actual group, it is in the object and so
1121 * there is no unique group to point to, hence the index */
1122 prop = RNA_def_property(srna, "group", PROP_INT, PROP_UNSIGNED);
1123 RNA_def_property_int_sdna(prop, NULL, "def_nr");
1124 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1125 RNA_def_property_ui_text(prop, "Group Index", "");
1126 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1127
1128 prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_FACTOR);
1129 RNA_def_property_range(prop, 0.0f, 1.0f);
1130 RNA_def_property_ui_text(prop, "Weight", "Vertex Weight");
1131 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1132 }
1133
rna_def_gpencil_stroke(BlenderRNA * brna)1134 static void rna_def_gpencil_stroke(BlenderRNA *brna)
1135 {
1136 StructRNA *srna;
1137 PropertyRNA *prop;
1138
1139 static const EnumPropertyItem stroke_display_mode_items[] = {
1140 {0, "SCREEN", 0, "Screen", "Stroke is in screen-space"},
1141 {GP_STROKE_3DSPACE, "3DSPACE", 0, "3D Space", "Stroke is in 3D-space"},
1142 {GP_STROKE_2DSPACE, "2DSPACE", 0, "2D Space", "Stroke is in 2D-space"},
1143 {GP_STROKE_2DIMAGE,
1144 "2DIMAGE",
1145 0,
1146 "2D Image",
1147 "Stroke is in 2D-space (but with special 'image' scaling)"},
1148 {0, NULL, 0, NULL, NULL},
1149 };
1150
1151 srna = RNA_def_struct(brna, "GPencilStroke", NULL);
1152 RNA_def_struct_sdna(srna, "bGPDstroke");
1153 RNA_def_struct_ui_text(srna, "Grease Pencil Stroke", "Freehand curve defining part of a sketch");
1154
1155 /* Points */
1156 prop = RNA_def_property(srna, "points", PROP_COLLECTION, PROP_NONE);
1157 RNA_def_property_collection_sdna(prop, NULL, "points", "totpoints");
1158 RNA_def_property_struct_type(prop, "GPencilStrokePoint");
1159 RNA_def_property_ui_text(prop, "Stroke Points", "Stroke data points");
1160 rna_def_gpencil_stroke_points_api(brna, prop);
1161
1162 /* vertex groups */
1163 prop = RNA_def_property(srna, "groups", PROP_COLLECTION, PROP_NONE);
1164 RNA_def_property_collection_funcs(prop,
1165 "rna_GpencilVertex_groups_begin",
1166 "rna_iterator_array_next",
1167 "rna_iterator_array_end",
1168 "rna_iterator_array_get",
1169 NULL,
1170 NULL,
1171 NULL,
1172 NULL);
1173 RNA_def_property_struct_type(prop, "GpencilVertexGroupElement");
1174 RNA_def_property_ui_text(
1175 prop, "Groups", "Weights for the vertex groups this vertex is member of");
1176
1177 /* Triangles */
1178 prop = RNA_def_property(srna, "triangles", PROP_COLLECTION, PROP_NONE);
1179 RNA_def_property_collection_sdna(prop, NULL, "triangles", "tot_triangles");
1180 RNA_def_property_struct_type(prop, "GPencilTriangle");
1181 RNA_def_property_ui_text(prop, "Triangles", "Triangulation data for HQ fill");
1182
1183 /* Material Index */
1184 prop = RNA_def_property(srna, "material_index", PROP_INT, PROP_NONE);
1185 RNA_def_property_int_sdna(prop, NULL, "mat_nr");
1186 RNA_def_property_ui_text(prop, "Material Index", "Index of material used in this stroke");
1187 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1188
1189 /* Settings */
1190 prop = RNA_def_property(srna, "display_mode", PROP_ENUM, PROP_NONE);
1191 RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
1192 RNA_def_property_enum_items(prop, stroke_display_mode_items);
1193 RNA_def_property_ui_text(prop, "Draw Mode", "Coordinate space that stroke is in");
1194 RNA_def_property_update(prop, 0, "rna_GPencil_update");
1195
1196 prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
1197 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STROKE_SELECT);
1198 RNA_def_property_boolean_funcs(prop, NULL, "rna_GPencil_stroke_select_set");
1199 RNA_def_property_ui_text(prop, "Select", "Stroke is selected for viewport editing");
1200 RNA_def_property_update(prop, 0, "rna_GPencil_update");
1201
1202 /* Cyclic: Draw a line from end to start point */
1203 prop = RNA_def_property(srna, "use_cyclic", PROP_BOOLEAN, PROP_NONE);
1204 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STROKE_CYCLIC);
1205 RNA_def_property_ui_text(prop, "Cyclic", "Enable cyclic drawing, closing the stroke");
1206 RNA_def_property_update(prop, 0, "rna_GPencil_update");
1207
1208 /* Caps mode */
1209 prop = RNA_def_property(srna, "start_cap_mode", PROP_ENUM, PROP_NONE);
1210 RNA_def_property_enum_sdna(prop, NULL, "caps[0]");
1211 RNA_def_property_enum_items(prop, rna_enum_gpencil_caps_modes_items);
1212 RNA_def_property_ui_text(prop, "Start Cap", "Stroke start extreme cap style");
1213 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1214
1215 prop = RNA_def_property(srna, "end_cap_mode", PROP_ENUM, PROP_NONE);
1216 RNA_def_property_enum_sdna(prop, NULL, "caps[1]");
1217 RNA_def_property_enum_items(prop, rna_enum_gpencil_caps_modes_items);
1218 RNA_def_property_ui_text(prop, "End Cap", "Stroke end extreme cap style");
1219 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1220
1221 /* No fill: The stroke never must fill area and must use fill color as stroke color
1222 * (this is a special flag for fill brush). */
1223 prop = RNA_def_property(srna, "is_nofill_stroke", PROP_BOOLEAN, PROP_NONE);
1224 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_STROKE_NOFILL);
1225 RNA_def_property_ui_text(prop, "No Fill", "Special stroke to use as boundary for filling areas");
1226 RNA_def_property_update(prop, 0, "rna_GPencil_update");
1227
1228 /* Line Thickness */
1229 prop = RNA_def_property(srna, "line_width", PROP_INT, PROP_PIXEL);
1230 RNA_def_property_int_sdna(prop, NULL, "thickness");
1231 RNA_def_property_range(prop, 1, 1000);
1232 RNA_def_property_ui_range(prop, 1, 10, 1, 0);
1233 RNA_def_property_ui_text(prop, "Thickness", "Thickness of stroke (in pixels)");
1234 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1235
1236 /* gradient control along y */
1237 prop = RNA_def_property(srna, "hardness", PROP_FLOAT, PROP_FACTOR);
1238 RNA_def_property_float_sdna(prop, NULL, "hardeness");
1239 RNA_def_property_range(prop, 0.001f, 1.0f);
1240 RNA_def_property_float_default(prop, 1.0f);
1241 RNA_def_property_ui_text(prop, "Hardness", "Amount of gradient along section of stroke");
1242 RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
1243 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1244
1245 /* Stroke bound box */
1246 prop = RNA_def_property(srna, "bound_box_min", PROP_FLOAT, PROP_XYZ);
1247 RNA_def_property_float_sdna(prop, NULL, "boundbox_min");
1248 RNA_def_property_array(prop, 3);
1249 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1250 RNA_def_property_ui_text(prop, "Boundbox Min", "");
1251
1252 prop = RNA_def_property(srna, "bound_box_max", PROP_FLOAT, PROP_XYZ);
1253 RNA_def_property_float_sdna(prop, NULL, "boundbox_max");
1254 RNA_def_property_array(prop, 3);
1255 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1256 RNA_def_property_ui_text(prop, "Boundbox Max", "");
1257
1258 /* gradient shape ratio */
1259 prop = RNA_def_property(srna, "aspect", PROP_FLOAT, PROP_XYZ);
1260 RNA_def_property_float_sdna(prop, NULL, "aspect_ratio");
1261 RNA_def_property_array(prop, 2);
1262 RNA_def_property_range(prop, 0.01f, 1.0f);
1263 RNA_def_property_float_default(prop, 1.0f);
1264 RNA_def_property_ui_text(prop, "Aspect", "");
1265 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1266
1267 /* UV translation. */
1268 prop = RNA_def_property(srna, "uv_translation", PROP_FLOAT, PROP_XYZ);
1269 RNA_def_property_float_sdna(prop, NULL, "uv_translation");
1270 RNA_def_property_array(prop, 2);
1271 RNA_def_property_float_default(prop, 0.0f);
1272 RNA_def_property_ui_text(prop, "UV Translation", "Translation of default UV position");
1273 RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
1274 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_uv_update");
1275
1276 /* UV rotation. */
1277 prop = RNA_def_property(srna, "uv_rotation", PROP_FLOAT, PROP_ANGLE);
1278 RNA_def_property_float_sdna(prop, NULL, "uv_rotation");
1279 RNA_def_property_float_default(prop, 0.0f);
1280 RNA_def_property_ui_text(prop, "UV Rotation", "Rotation of the UV");
1281 RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
1282 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_uv_update");
1283
1284 /* UV scale. */
1285 prop = RNA_def_property(srna, "uv_scale", PROP_FLOAT, PROP_NONE);
1286 RNA_def_property_float_sdna(prop, NULL, "uv_scale");
1287 RNA_def_property_float_default(prop, 1.0f);
1288 RNA_def_property_range(prop, 0.01f, 100.0f);
1289 RNA_def_property_ui_text(prop, "UV Scale", "Scale of the UV");
1290 RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
1291 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_uv_update");
1292
1293 /* Vertex Color for Fill. */
1294 prop = RNA_def_property(srna, "vertex_color_fill", PROP_FLOAT, PROP_COLOR);
1295 RNA_def_property_float_sdna(prop, NULL, "vert_color_fill");
1296 RNA_def_property_array(prop, 4);
1297 RNA_def_property_range(prop, 0.0f, 1.0f);
1298 RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1299 RNA_def_property_ui_text(
1300 prop, "Vertex Fill Color", "Color used to mix with fill color to get final color");
1301 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1302 }
1303
rna_def_gpencil_strokes_api(BlenderRNA * brna,PropertyRNA * cprop)1304 static void rna_def_gpencil_strokes_api(BlenderRNA *brna, PropertyRNA *cprop)
1305 {
1306 StructRNA *srna;
1307
1308 FunctionRNA *func;
1309 PropertyRNA *parm;
1310
1311 RNA_def_property_srna(cprop, "GPencilStrokes");
1312 srna = RNA_def_struct(brna, "GPencilStrokes", NULL);
1313 RNA_def_struct_sdna(srna, "bGPDframe");
1314 RNA_def_struct_ui_text(srna, "Grease Pencil Frames", "Collection of grease pencil stroke");
1315
1316 func = RNA_def_function(srna, "new", "rna_GPencil_stroke_new");
1317 RNA_def_function_ui_description(func, "Add a new grease pencil stroke");
1318 parm = RNA_def_pointer(func, "stroke", "GPencilStroke", "", "The newly created stroke");
1319 RNA_def_function_return(func, parm);
1320
1321 func = RNA_def_function(srna, "remove", "rna_GPencil_stroke_remove");
1322 RNA_def_function_ui_description(func, "Remove a grease pencil stroke");
1323 RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
1324 parm = RNA_def_pointer(func, "stroke", "GPencilStroke", "Stroke", "The stroke to remove");
1325 RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
1326 RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
1327
1328 func = RNA_def_function(srna, "close", "rna_GPencil_stroke_close");
1329 RNA_def_function_ui_description(func, "Close a grease pencil stroke adding geometry");
1330 RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID);
1331 parm = RNA_def_pointer(func, "stroke", "GPencilStroke", "Stroke", "The stroke to close");
1332 RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
1333 RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
1334 }
1335
rna_def_gpencil_frame(BlenderRNA * brna)1336 static void rna_def_gpencil_frame(BlenderRNA *brna)
1337 {
1338 StructRNA *srna;
1339 PropertyRNA *prop;
1340
1341 FunctionRNA *func;
1342
1343 srna = RNA_def_struct(brna, "GPencilFrame", NULL);
1344 RNA_def_struct_sdna(srna, "bGPDframe");
1345 RNA_def_struct_ui_text(
1346 srna, "Grease Pencil Frame", "Collection of related sketches on a particular frame");
1347
1348 /* Strokes */
1349 prop = RNA_def_property(srna, "strokes", PROP_COLLECTION, PROP_NONE);
1350 RNA_def_property_collection_sdna(prop, NULL, "strokes", NULL);
1351 RNA_def_property_struct_type(prop, "GPencilStroke");
1352 RNA_def_property_ui_text(prop, "Strokes", "Freehand curves defining the sketch on this frame");
1353 rna_def_gpencil_strokes_api(brna, prop);
1354
1355 /* Frame Number */
1356 prop = RNA_def_property(srna, "frame_number", PROP_INT, PROP_NONE);
1357 RNA_def_property_int_sdna(prop, NULL, "framenum");
1358 /* XXX note: this cannot occur on the same frame as another sketch */
1359 RNA_def_property_range(prop, -MAXFRAME, MAXFRAME);
1360 RNA_def_property_ui_text(prop, "Frame Number", "The frame on which this sketch appears");
1361
1362 prop = RNA_def_property(srna, "keyframe_type", PROP_ENUM, PROP_NONE);
1363 RNA_def_property_enum_sdna(prop, NULL, "key_type");
1364 RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
1365 RNA_def_property_enum_items(prop, rna_enum_keyframe_type_items);
1366 RNA_def_property_ui_text(prop, "Keyframe Type", "Type of keyframe");
1367 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1368
1369 /* Flags */
1370 prop = RNA_def_property(srna, "is_edited", PROP_BOOLEAN, PROP_NONE);
1371 RNA_def_property_boolean_sdna(
1372 prop, NULL, "flag", GP_FRAME_PAINT); /* XXX should it be editable? */
1373 RNA_def_property_ui_text(prop, "Paint Lock", "Frame is being edited (painted on)");
1374
1375 prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
1376 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_FRAME_SELECT);
1377 RNA_def_property_ui_text(prop, "Select", "Frame is selected for editing in the Dope Sheet");
1378
1379 /* API */
1380 func = RNA_def_function(srna, "clear", "rna_GPencil_frame_clear");
1381 RNA_def_function_ui_description(func, "Remove all the grease pencil frame data");
1382 }
1383
rna_def_gpencil_frames_api(BlenderRNA * brna,PropertyRNA * cprop)1384 static void rna_def_gpencil_frames_api(BlenderRNA *brna, PropertyRNA *cprop)
1385 {
1386 StructRNA *srna;
1387
1388 FunctionRNA *func;
1389 PropertyRNA *parm;
1390
1391 RNA_def_property_srna(cprop, "GPencilFrames");
1392 srna = RNA_def_struct(brna, "GPencilFrames", NULL);
1393 RNA_def_struct_sdna(srna, "bGPDlayer");
1394 RNA_def_struct_ui_text(srna, "Grease Pencil Frames", "Collection of grease pencil frames");
1395
1396 func = RNA_def_function(srna, "new", "rna_GPencil_frame_new");
1397 RNA_def_function_ui_description(func, "Add a new grease pencil frame");
1398 RNA_def_function_flag(func, FUNC_USE_REPORTS);
1399 parm = RNA_def_int(func,
1400 "frame_number",
1401 1,
1402 MINAFRAME,
1403 MAXFRAME,
1404 "Frame Number",
1405 "The frame on which this sketch appears",
1406 MINAFRAME,
1407 MAXFRAME);
1408 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1409 RNA_def_boolean(func, "active", 0, "Active", "");
1410 parm = RNA_def_pointer(func, "frame", "GPencilFrame", "", "The newly created frame");
1411 RNA_def_function_return(func, parm);
1412
1413 func = RNA_def_function(srna, "remove", "rna_GPencil_frame_remove");
1414 RNA_def_function_ui_description(func, "Remove a grease pencil frame");
1415 RNA_def_function_flag(func, FUNC_USE_REPORTS);
1416 parm = RNA_def_pointer(func, "frame", "GPencilFrame", "Frame", "The frame to remove");
1417 RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
1418 RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
1419
1420 func = RNA_def_function(srna, "copy", "rna_GPencil_frame_copy");
1421 RNA_def_function_ui_description(func, "Copy a grease pencil frame");
1422 parm = RNA_def_pointer(func, "source", "GPencilFrame", "Source", "The source frame");
1423 RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
1424 parm = RNA_def_pointer(func, "copy", "GPencilFrame", "", "The newly copied frame");
1425 RNA_def_function_return(func, parm);
1426 }
1427
rna_def_gpencil_layers_mask_api(BlenderRNA * brna,PropertyRNA * cprop)1428 static void rna_def_gpencil_layers_mask_api(BlenderRNA *brna, PropertyRNA *cprop)
1429 {
1430 StructRNA *srna;
1431 PropertyRNA *prop;
1432
1433 FunctionRNA *func;
1434 PropertyRNA *parm;
1435
1436 RNA_def_property_srna(cprop, "GreasePencilMaskLayers");
1437 srna = RNA_def_struct(brna, "GreasePencilMaskLayers", NULL);
1438 RNA_def_struct_sdna(srna, "bGPDlayer");
1439 RNA_def_struct_ui_text(
1440 srna, "Grease Pencil Mask Layers", "Collection of grease pencil masking layers");
1441
1442 prop = RNA_def_property(srna, "active_mask_index", PROP_INT, PROP_UNSIGNED);
1443 RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1444 RNA_def_property_int_funcs(prop,
1445 "rna_GPencil_active_mask_index_get",
1446 "rna_GPencil_active_mask_index_set",
1447 "rna_GPencil_active_mask_index_range");
1448 RNA_def_property_ui_text(prop, "Active Layer Mask Index", "Active index in layer mask array");
1449
1450 func = RNA_def_function(srna, "add", "rna_GPencil_layer_mask_add");
1451 RNA_def_function_ui_description(func, "Add a layer to mask list");
1452 parm = RNA_def_pointer(func, "layer", "GPencilLayer", "", "Layer to add as mask");
1453 RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
1454 RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
1455
1456 func = RNA_def_function(srna, "remove", "rna_GPencil_layer_mask_remove");
1457 RNA_def_function_ui_description(func, "Remove a layer from mask list");
1458 RNA_def_function_flag(func, FUNC_USE_REPORTS);
1459 parm = RNA_def_pointer(func, "mask", "GPencilLayerMask", "", "Mask to remove");
1460 RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
1461 RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
1462 }
1463
rna_def_gpencil_layer_mask(BlenderRNA * brna)1464 static void rna_def_gpencil_layer_mask(BlenderRNA *brna)
1465 {
1466 StructRNA *srna;
1467 PropertyRNA *prop;
1468
1469 srna = RNA_def_struct(brna, "GPencilLayerMask", NULL);
1470 RNA_def_struct_sdna(srna, "bGPDlayer_Mask");
1471 RNA_def_struct_ui_text(srna, "Grease Pencil Masking Layers", "List of Mask Layers");
1472 RNA_def_struct_path_func(srna, "rna_GPencilLayerMask_path");
1473
1474 /* Name */
1475 prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
1476 RNA_def_property_ui_text(prop, "Layer", "Mask layer name");
1477 RNA_def_property_string_funcs(prop, NULL, NULL, "rna_GPencilLayer_mask_info_set");
1478 RNA_def_struct_name_property(srna, prop);
1479 RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1480 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_RENAME, NULL);
1481
1482 /* Flags */
1483 prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
1484 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_MASK_HIDE);
1485 RNA_def_property_ui_icon(prop, ICON_HIDE_OFF, -1);
1486 RNA_def_property_ui_text(prop, "Hide", "Set mask Visibility");
1487 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1488
1489 prop = RNA_def_property(srna, "invert", PROP_BOOLEAN, PROP_NONE);
1490 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_MASK_INVERT);
1491 RNA_def_property_ui_icon(prop, ICON_CLIPUV_HLT, -1);
1492 RNA_def_property_ui_text(prop, "Invert", "Invert mask");
1493 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1494 }
1495
rna_def_gpencil_layer(BlenderRNA * brna)1496 static void rna_def_gpencil_layer(BlenderRNA *brna)
1497 {
1498 StructRNA *srna;
1499 PropertyRNA *prop;
1500
1501 FunctionRNA *func;
1502 static const float default_onion_color_b[] = {0.302f, 0.851f, 0.302f};
1503 static const float default_onion_color_a[] = {0.250f, 0.1f, 1.0f};
1504
1505 srna = RNA_def_struct(brna, "GPencilLayer", NULL);
1506 RNA_def_struct_sdna(srna, "bGPDlayer");
1507 RNA_def_struct_ui_text(srna, "Grease Pencil Layer", "Collection of related sketches");
1508 RNA_def_struct_path_func(srna, "rna_GPencilLayer_path");
1509
1510 /* Name */
1511 prop = RNA_def_property(srna, "info", PROP_STRING, PROP_NONE);
1512 RNA_def_property_ui_text(prop, "Info", "Layer name");
1513 RNA_def_property_string_funcs(prop, NULL, NULL, "rna_GPencilLayer_info_set");
1514 RNA_def_struct_name_property(srna, prop);
1515 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_RENAME, "rna_GPencil_update");
1516
1517 /* Frames */
1518 prop = RNA_def_property(srna, "frames", PROP_COLLECTION, PROP_NONE);
1519 RNA_def_property_collection_sdna(prop, NULL, "frames", NULL);
1520 RNA_def_property_struct_type(prop, "GPencilFrame");
1521 RNA_def_property_ui_text(prop, "Frames", "Sketches for this layer on different frames");
1522 rna_def_gpencil_frames_api(brna, prop);
1523
1524 /* Mask Layers */
1525 prop = RNA_def_property(srna, "mask_layers", PROP_COLLECTION, PROP_NONE);
1526 RNA_def_property_collection_sdna(prop, NULL, "mask_layers", NULL);
1527 RNA_def_property_struct_type(prop, "GPencilLayerMask");
1528 RNA_def_property_ui_text(prop, "Masks", "List of Masking Layers");
1529 rna_def_gpencil_layers_mask_api(brna, prop);
1530
1531 /* Active Frame */
1532 prop = RNA_def_property(srna, "active_frame", PROP_POINTER, PROP_NONE);
1533 RNA_def_property_pointer_sdna(prop, NULL, "actframe");
1534 RNA_def_property_ui_text(prop, "Active Frame", "Frame currently being displayed for this layer");
1535 RNA_def_property_editable_func(prop, "rna_GPencilLayer_active_frame_editable");
1536 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
1537
1538 /* Layer Opacity */
1539 prop = RNA_def_property(srna, "opacity", PROP_FLOAT, PROP_NONE);
1540 RNA_def_property_float_sdna(prop, NULL, "opacity");
1541 RNA_def_property_range(prop, 0.0, 1.0f);
1542 RNA_def_property_ui_text(prop, "Opacity", "Layer Opacity");
1543 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1544
1545 /* layer channel color (grease pencil) */
1546 prop = RNA_def_property(srna, "channel_color", PROP_FLOAT, PROP_COLOR_GAMMA);
1547 RNA_def_property_float_sdna(prop, NULL, "color");
1548 RNA_def_property_array(prop, 3);
1549 RNA_def_property_range(prop, 0.0f, 1.0f);
1550 RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1551 RNA_def_property_ui_text(
1552 prop, "Custom Channel Color", "Custom color for animation channel in Dopesheet");
1553 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1554
1555 /* Stroke Drawing Color (Annotations) */
1556 prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
1557 RNA_def_property_array(prop, 3);
1558 RNA_def_property_range(prop, 0.0f, 1.0f);
1559 RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1560 RNA_def_property_ui_text(prop, "Color", "Color for all strokes in this layer");
1561 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1562
1563 /* Line Thickness (Annotations) */
1564 prop = RNA_def_property(srna, "thickness", PROP_INT, PROP_PIXEL);
1565 RNA_def_property_int_sdna(prop, NULL, "thickness");
1566 RNA_def_property_range(prop, 1, 10);
1567 RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1568 RNA_def_property_ui_text(prop, "Thickness", "Thickness of annotation strokes");
1569 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1570
1571 /* Tint Color */
1572 prop = RNA_def_property(srna, "tint_color", PROP_FLOAT, PROP_COLOR);
1573 RNA_def_property_float_sdna(prop, NULL, "tintcolor");
1574 RNA_def_property_array(prop, 3);
1575 RNA_def_property_range(prop, 0.0f, 1.0f);
1576 RNA_def_property_ui_text(prop, "Tint Color", "Color for tinting stroke colors");
1577 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1578
1579 /* Tint factor */
1580 prop = RNA_def_property(srna, "tint_factor", PROP_FLOAT, PROP_FACTOR);
1581 RNA_def_property_float_sdna(prop, NULL, "tintcolor[3]");
1582 RNA_def_property_range(prop, 0.0, 1.0f);
1583 RNA_def_property_ui_text(prop, "Tint Factor", "Factor of tinting color");
1584 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1585
1586 /* Vertex Paint opacity factor */
1587 prop = RNA_def_property(srna, "vertex_paint_opacity", PROP_FLOAT, PROP_FACTOR);
1588 RNA_def_property_float_sdna(prop, NULL, "vertex_paint_opacity");
1589 RNA_def_property_range(prop, 0.0f, 1.0f);
1590 RNA_def_property_float_default(prop, 1.0f);
1591 RNA_def_property_ui_text(prop, "Vertex Paint Opacity", "Vertex Paint mix factor");
1592 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1593
1594 /* Line Thickness Change */
1595 prop = RNA_def_property(srna, "line_change", PROP_INT, PROP_PIXEL);
1596 RNA_def_property_int_sdna(prop, NULL, "line_change");
1597 RNA_def_property_range(prop, -300, 300);
1598 RNA_def_property_ui_range(prop, -100, 100, 1.0, 1);
1599 RNA_def_property_ui_text(
1600 prop, "Thickness Change", "Thickness change to apply to current strokes (in pixels)");
1601 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1602
1603 /* Onion-Skinning */
1604 prop = RNA_def_property(srna, "use_onion_skinning", PROP_BOOLEAN, PROP_NONE);
1605 RNA_def_property_boolean_sdna(prop, NULL, "onion_flag", GP_LAYER_ONIONSKIN);
1606 RNA_def_property_ui_text(
1607 prop, "Onion Skinning", "Display onion skins before and after the current frame");
1608 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1609
1610 prop = RNA_def_property(srna, "use_annotation_onion_skinning", PROP_BOOLEAN, PROP_NONE);
1611 RNA_def_property_boolean_sdna(prop, NULL, "onion_flag", GP_LAYER_ONIONSKIN);
1612 RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1613 RNA_def_property_ui_text(
1614 prop, "Onion Skinning", "Display annotation onion skins before and after the current frame");
1615 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1616
1617 prop = RNA_def_property(srna, "annotation_onion_before_range", PROP_INT, PROP_NONE);
1618 RNA_def_property_int_sdna(prop, NULL, "gstep");
1619 RNA_def_property_range(prop, -1, 120);
1620 RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1621 RNA_def_property_ui_text(
1622 prop, "Frames Before", "Maximum number of frames to show before current frame");
1623 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1624
1625 prop = RNA_def_property(srna, "annotation_onion_after_range", PROP_INT, PROP_NONE);
1626 RNA_def_property_int_sdna(prop, NULL, "gstep_next");
1627 RNA_def_property_range(prop, -1, 120);
1628 RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1629 RNA_def_property_ui_text(
1630 prop, "Frames After", "Maximum number of frames to show after current frame");
1631 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1632
1633 prop = RNA_def_property(srna, "annotation_onion_before_color", PROP_FLOAT, PROP_COLOR_GAMMA);
1634 RNA_def_property_float_sdna(prop, NULL, "gcolor_prev");
1635 RNA_def_property_array(prop, 3);
1636 RNA_def_property_range(prop, 0.0f, 1.0f);
1637 RNA_def_property_float_array_default(prop, default_onion_color_b);
1638 RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1639 RNA_def_property_ui_text(prop, "Before Color", "Base color for ghosts before the active frame");
1640 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1641
1642 prop = RNA_def_property(srna, "annotation_onion_after_color", PROP_FLOAT, PROP_COLOR_GAMMA);
1643 RNA_def_property_float_sdna(prop, NULL, "gcolor_next");
1644 RNA_def_property_array(prop, 3);
1645 RNA_def_property_range(prop, 0.0f, 1.0f);
1646 RNA_def_property_float_array_default(prop, default_onion_color_a);
1647 RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1648 RNA_def_property_ui_text(prop, "After Color", "Base color for ghosts after the active frame");
1649 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1650
1651 /* pass index for compositing and modifiers */
1652 prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_UNSIGNED);
1653 RNA_def_property_int_sdna(prop, NULL, "pass_index");
1654 RNA_def_property_ui_text(prop, "Pass Index", "Index number for the \"Layer Index\" pass");
1655 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1656
1657 prop = RNA_def_property(srna, "viewlayer_render", PROP_STRING, PROP_NONE);
1658 RNA_def_property_string_sdna(prop, NULL, "viewlayername");
1659 RNA_def_property_ui_text(
1660 prop,
1661 "ViewLayer",
1662 "Only include Layer in this View Layer render output (leave blank to include always)");
1663
1664 /* blend mode */
1665 prop = RNA_def_property(srna, "blend_mode", PROP_ENUM, PROP_NONE);
1666 RNA_def_property_enum_sdna(prop, NULL, "blend_mode");
1667 RNA_def_property_enum_items(prop, rna_enum_layer_blend_modes_items);
1668 RNA_def_property_ui_text(prop, "Blend Mode", "Blend mode");
1669 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1670
1671 /* Flags */
1672 prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
1673 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_HIDE);
1674 RNA_def_property_ui_icon(prop, ICON_HIDE_OFF, -1);
1675 RNA_def_property_ui_text(prop, "Hide", "Set layer Visibility");
1676 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1677
1678 prop = RNA_def_property(srna, "annotation_hide", PROP_BOOLEAN, PROP_NONE);
1679 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_HIDE);
1680 RNA_def_property_ui_icon(prop, ICON_HIDE_OFF, -1);
1681 RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1682 RNA_def_property_ui_text(prop, "Hide", "Set annotation Visibility");
1683 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1684
1685 prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE);
1686 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_LOCKED);
1687 RNA_def_property_ui_icon(prop, ICON_UNLOCKED, 1);
1688 RNA_def_property_ui_text(
1689 prop, "Locked", "Protect layer from further editing and/or frame changes");
1690 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1691
1692 prop = RNA_def_property(srna, "lock_frame", PROP_BOOLEAN, PROP_NONE);
1693 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_FRAMELOCK);
1694 RNA_def_property_ui_icon(prop, ICON_UNLOCKED, 1);
1695 RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1696 RNA_def_property_ui_text(prop, "Frame Locked", "Lock current frame displayed by layer");
1697 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1698
1699 prop = RNA_def_property(srna, "lock_material", PROP_BOOLEAN, PROP_NONE);
1700 RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GP_LAYER_UNLOCK_COLOR);
1701 RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1702 RNA_def_property_ui_text(
1703 prop, "Disallow Locked Materials Editing", "Avoids editing locked materials in the layer");
1704 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL);
1705
1706 prop = RNA_def_property(srna, "use_mask_layer", PROP_BOOLEAN, PROP_NONE);
1707 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_USE_MASK);
1708 RNA_def_property_ui_text(prop, "Mask Layer", "Mask pixels from underlying layers drawing");
1709 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1710
1711 prop = RNA_def_property(srna, "use_lights", PROP_BOOLEAN, PROP_NONE);
1712 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_USE_LIGHTS);
1713 RNA_def_property_ui_text(
1714 prop, "Use Lights", "Enable the use of lights on stroke and fill materials");
1715 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1716
1717 /* solo mode: Only display frames with keyframe */
1718 prop = RNA_def_property(srna, "use_solo_mode", PROP_BOOLEAN, PROP_NONE);
1719 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_SOLO_MODE);
1720 RNA_def_property_ui_text(
1721 prop, "Solo Mode", "In Paint mode display only layers with keyframe in current frame");
1722 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1723
1724 /* Layer is used as Ruler. */
1725 prop = RNA_def_property(srna, "is_ruler", PROP_BOOLEAN, PROP_NONE);
1726 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_IS_RULER);
1727 RNA_def_property_ui_text(prop, "Ruler", "This is a special ruler layer");
1728 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1729
1730 prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE);
1731 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_SELECT);
1732 RNA_def_property_ui_text(prop, "Select", "Layer is selected for editing in the Dope Sheet");
1733 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_SELECTED, "rna_GPencil_update");
1734
1735 prop = RNA_def_property(srna, "show_points", PROP_BOOLEAN, PROP_NONE);
1736 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_DRAWDEBUG);
1737 RNA_def_property_ui_text(
1738 prop, "Show Points", "Draw the points which make up the strokes (for debugging purposes)");
1739 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1740
1741 /* In Front */
1742 prop = RNA_def_property(srna, "show_in_front", PROP_BOOLEAN, PROP_NONE);
1743 RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GP_LAYER_NO_XRAY);
1744 RNA_def_property_ui_text(prop, "In Front", "Make the layer draw in front of objects");
1745 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1746
1747 /* Parent object */
1748 prop = RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
1749 RNA_def_property_pointer_funcs(prop, NULL, "rna_GPencilLayer_parent_set", NULL, NULL);
1750 RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_SELF_CHECK);
1751 RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
1752 RNA_def_property_ui_text(prop, "Parent", "Parent Object");
1753 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_dependency_update");
1754
1755 /* parent type */
1756 prop = RNA_def_property(srna, "parent_type", PROP_ENUM, PROP_NONE);
1757 RNA_def_property_enum_bitflag_sdna(prop, NULL, "partype");
1758 RNA_def_property_enum_items(prop, parent_type_items);
1759 RNA_def_property_enum_funcs(
1760 prop, NULL, "rna_GPencilLayer_parent_type_set", "rna_Object_parent_type_itemf");
1761 RNA_def_property_ui_text(prop, "Parent Type", "Type of parent relation");
1762 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_dependency_update");
1763
1764 /* parent bone */
1765 prop = RNA_def_property(srna, "parent_bone", PROP_STRING, PROP_NONE);
1766 RNA_def_property_string_sdna(prop, NULL, "parsubstr");
1767 RNA_def_property_string_funcs(prop, NULL, NULL, "rna_GPencilLayer_parent_bone_set");
1768 RNA_def_property_ui_text(
1769 prop, "Parent Bone", "Name of parent bone in case of a bone parenting relation");
1770 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_dependency_update");
1771
1772 /* matrix */
1773 prop = RNA_def_property(srna, "matrix_inverse", PROP_FLOAT, PROP_MATRIX);
1774 RNA_def_property_float_sdna(prop, NULL, "inverse");
1775 RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
1776 RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
1777 RNA_def_property_ui_text(prop, "Inverse Matrix", "Parent inverse transformation matrix");
1778 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1779
1780 /* read only parented flag */
1781 prop = RNA_def_property(srna, "is_parented", PROP_BOOLEAN, PROP_NONE);
1782 RNA_def_property_boolean_funcs(prop, "rna_GPencilLayer_is_parented_get", NULL);
1783 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1784 RNA_def_property_ui_text(prop, "Is Parented", "True when the layer parent object is set");
1785
1786 /* Layers API */
1787 func = RNA_def_function(srna, "clear", "rna_GPencil_layer_clear");
1788 RNA_def_function_ui_description(func, "Remove all the grease pencil layer data");
1789 }
1790
rna_def_gpencil_layers_api(BlenderRNA * brna,PropertyRNA * cprop)1791 static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop)
1792 {
1793 StructRNA *srna;
1794 PropertyRNA *prop;
1795
1796 FunctionRNA *func;
1797 PropertyRNA *parm;
1798
1799 RNA_def_property_srna(cprop, "GreasePencilLayers");
1800 srna = RNA_def_struct(brna, "GreasePencilLayers", NULL);
1801 RNA_def_struct_sdna(srna, "bGPdata");
1802 RNA_def_struct_ui_text(srna, "Grease Pencil Layers", "Collection of grease pencil layers");
1803
1804 func = RNA_def_function(srna, "new", "rna_GPencil_layer_new");
1805 RNA_def_function_ui_description(func, "Add a new grease pencil layer");
1806 parm = RNA_def_string(func, "name", "GPencilLayer", MAX_NAME, "Name", "Name of the layer");
1807 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1808 RNA_def_boolean(
1809 func, "set_active", true, "Set Active", "Set the newly created layer to the active layer");
1810 parm = RNA_def_pointer(func, "layer", "GPencilLayer", "", "The newly created layer");
1811 RNA_def_function_return(func, parm);
1812
1813 func = RNA_def_function(srna, "remove", "rna_GPencil_layer_remove");
1814 RNA_def_function_ui_description(func, "Remove a grease pencil layer");
1815 RNA_def_function_flag(func, FUNC_USE_REPORTS);
1816 parm = RNA_def_pointer(func, "layer", "GPencilLayer", "", "The layer to remove");
1817 RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
1818 RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
1819
1820 func = RNA_def_function(srna, "move", "rna_GPencil_layer_move");
1821 RNA_def_function_ui_description(func, "Move a grease pencil layer in the layer stack");
1822 RNA_def_function_flag(func, FUNC_USE_REPORTS);
1823 parm = RNA_def_pointer(func, "layer", "GPencilLayer", "", "The layer to move");
1824 RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR);
1825 RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0);
1826 parm = RNA_def_enum(
1827 func, "type", rna_enum_gplayer_move_type_items, 1, "", "Direction of movement");
1828 RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
1829
1830 prop = RNA_def_property(srna, "active", PROP_POINTER, PROP_NONE);
1831 RNA_def_property_struct_type(prop, "GPencilLayer");
1832 RNA_def_property_pointer_funcs(
1833 prop, "rna_GPencil_active_layer_get", "rna_GPencil_active_layer_set", NULL, NULL);
1834 RNA_def_property_flag(prop, PROP_EDITABLE);
1835 RNA_def_property_ui_text(prop, "Active Layer", "Active grease pencil layer");
1836 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_SELECTED, NULL);
1837
1838 prop = RNA_def_property(srna, "active_index", PROP_INT, PROP_UNSIGNED);
1839 RNA_def_property_int_funcs(prop,
1840 "rna_GPencil_active_layer_index_get",
1841 "rna_GPencil_active_layer_index_set",
1842 "rna_GPencil_active_layer_index_range");
1843 RNA_def_property_ui_text(prop, "Active Layer Index", "Index of active grease pencil layer");
1844 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA | NA_SELECTED, NULL);
1845
1846 /* Active Layer - As an enum (for selecting active layer for annotations) */
1847 prop = RNA_def_property(srna, "active_note", PROP_ENUM, PROP_NONE);
1848 RNA_def_property_enum_funcs(prop,
1849 "rna_GPencil_active_layer_index_get",
1850 "rna_GPencil_active_layer_index_set",
1851 "rna_GPencil_active_layer_itemf");
1852 RNA_def_property_enum_items(
1853 prop, DummyRNA_DEFAULT_items); /* purely dynamic, as it maps to user-data */
1854 RNA_def_property_ui_text(prop, "Active Note", "Note/Layer to add annotation strokes to");
1855 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1856 }
1857
rna_def_gpencil_grid(BlenderRNA * brna)1858 static void rna_def_gpencil_grid(BlenderRNA *brna)
1859 {
1860 StructRNA *srna;
1861 PropertyRNA *prop;
1862
1863 static const float default_grid_color[] = {0.5f, 0.5f, 0.5f};
1864
1865 srna = RNA_def_struct(brna, "GreasePencilGrid", NULL);
1866 RNA_def_struct_sdna(srna, "bGPgrid");
1867 RNA_def_struct_nested(brna, srna, "GreasePencil");
1868
1869 RNA_def_struct_path_func(srna, "rna_GreasePencilGrid_path");
1870 RNA_def_struct_ui_text(
1871 srna, "Grid and Canvas Settings", "Settings for grid and canvas in 3D viewport");
1872
1873 prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
1874 RNA_def_property_float_sdna(prop, NULL, "scale");
1875 RNA_def_property_range(prop, 0.01f, FLT_MAX);
1876 RNA_def_property_float_default(prop, 1.0f);
1877 RNA_def_property_ui_text(prop, "Grid Scale", "Grid scale");
1878 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1879
1880 prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
1881 RNA_def_property_float_sdna(prop, NULL, "color");
1882 RNA_def_property_array(prop, 3);
1883 RNA_def_property_range(prop, 0.0f, 1.0f);
1884 RNA_def_property_float_array_default(prop, default_grid_color);
1885 RNA_def_property_ui_text(prop, "Grid Color", "Color for grid lines");
1886 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1887
1888 prop = RNA_def_property(srna, "lines", PROP_INT, PROP_NONE);
1889 RNA_def_property_int_sdna(prop, NULL, "lines");
1890 RNA_def_property_range(prop, 0, SHRT_MAX);
1891 RNA_def_property_int_default(prop, GP_DEFAULT_GRID_LINES);
1892 RNA_def_property_ui_text(
1893 prop, "Grid Subdivisions", "Number of subdivisions in each side of symmetry line");
1894 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1895
1896 prop = RNA_def_property(srna, "offset", PROP_FLOAT, PROP_TRANSLATION);
1897 RNA_def_property_float_sdna(prop, NULL, "offset");
1898 RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
1899 RNA_def_property_array(prop, 2);
1900 RNA_def_property_ui_text(prop, "Offset", "Offset of the canvas");
1901 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1902 }
1903
rna_def_gpencil_data(BlenderRNA * brna)1904 static void rna_def_gpencil_data(BlenderRNA *brna)
1905 {
1906 StructRNA *srna;
1907 PropertyRNA *prop;
1908 FunctionRNA *func;
1909
1910 static float default_1[4] = {0.6f, 0.6f, 0.6f, 0.5f};
1911 static float onion_dft1[3] = {0.145098f, 0.419608f, 0.137255f}; /* green */
1912 static float onion_dft2[3] = {0.125490f, 0.082353f, 0.529412f}; /* blue */
1913
1914 static const EnumPropertyItem stroke_thickness_items[] = {
1915 {0, "WORLDSPACE", 0, "World Space", "Set stroke thickness relative to the world space"},
1916 {GP_DATA_STROKE_KEEPTHICKNESS,
1917 "SCREENSPACE",
1918 0,
1919 "Screen Space",
1920 "Set stroke thickness relative to the screen space"},
1921 {0, NULL, 0, NULL, NULL},
1922 };
1923
1924 srna = RNA_def_struct(brna, "GreasePencil", "ID");
1925 RNA_def_struct_sdna(srna, "bGPdata");
1926 RNA_def_struct_ui_text(srna, "Grease Pencil", "Freehand annotation sketchbook");
1927 RNA_def_struct_ui_icon(srna, ICON_OUTLINER_DATA_GREASEPENCIL);
1928
1929 /* Layers */
1930 prop = RNA_def_property(srna, "layers", PROP_COLLECTION, PROP_NONE);
1931 RNA_def_property_collection_sdna(prop, NULL, "layers", NULL);
1932 RNA_def_property_struct_type(prop, "GPencilLayer");
1933 RNA_def_property_ui_text(prop, "Layers", "");
1934 rna_def_gpencil_layers_api(brna, prop);
1935
1936 /* Animation Data */
1937 rna_def_animdata_common(srna);
1938
1939 /* materials */
1940 prop = RNA_def_property(srna, "materials", PROP_COLLECTION, PROP_NONE);
1941 RNA_def_property_collection_sdna(prop, NULL, "mat", "totcol");
1942 RNA_def_property_struct_type(prop, "Material");
1943 RNA_def_property_ui_text(prop, "Materials", "");
1944 RNA_def_property_srna(prop, "IDMaterials"); /* see rna_ID.c */
1945 RNA_def_property_collection_funcs(
1946 prop, NULL, NULL, NULL, NULL, NULL, NULL, NULL, "rna_IDMaterials_assign_int");
1947
1948 /* Depth */
1949 prop = RNA_def_property(srna, "stroke_depth_order", PROP_ENUM, PROP_NONE);
1950 RNA_def_property_enum_sdna(prop, NULL, "draw_mode");
1951 RNA_def_property_enum_items(prop, rna_enum_gpencil_stroke_depth_order_items);
1952 RNA_def_property_ui_text(
1953 prop,
1954 "Stroke Depth Order",
1955 "Defines how the strokes are ordered in 3D space (for objects not displayed 'In Front')");
1956 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
1957
1958 /* Flags */
1959 prop = RNA_def_property(srna, "use_stroke_edit_mode", PROP_BOOLEAN, PROP_NONE);
1960 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_STROKE_EDITMODE);
1961 RNA_def_property_ui_text(
1962 prop, "Stroke Edit Mode", "Edit Grease Pencil strokes instead of viewport data");
1963 RNA_def_property_update(
1964 prop, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, "rna_GPencil_editmode_update");
1965
1966 prop = RNA_def_property(srna, "is_stroke_paint_mode", PROP_BOOLEAN, PROP_NONE);
1967 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_STROKE_PAINTMODE);
1968 RNA_def_property_ui_text(prop, "Stroke Paint Mode", "Draw Grease Pencil strokes on click/drag");
1969 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1970 RNA_def_property_update(
1971 prop, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, "rna_GPencil_editmode_update");
1972
1973 prop = RNA_def_property(srna, "is_stroke_sculpt_mode", PROP_BOOLEAN, PROP_NONE);
1974 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_STROKE_SCULPTMODE);
1975 RNA_def_property_ui_text(
1976 prop, "Stroke Sculpt Mode", "Sculpt Grease Pencil strokes instead of viewport data");
1977 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1978 RNA_def_property_update(
1979 prop, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, "rna_GPencil_editmode_update");
1980
1981 prop = RNA_def_property(srna, "is_stroke_weight_mode", PROP_BOOLEAN, PROP_NONE);
1982 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_STROKE_WEIGHTMODE);
1983 RNA_def_property_ui_text(prop, "Stroke Weight Paint Mode", "Grease Pencil weight paint");
1984 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1985 RNA_def_property_update(
1986 prop, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, "rna_GPencil_editmode_update");
1987
1988 prop = RNA_def_property(srna, "is_stroke_vertex_mode", PROP_BOOLEAN, PROP_NONE);
1989 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_STROKE_VERTEXMODE);
1990 RNA_def_property_ui_text(prop, "Stroke Vertex Paint Mode", "Grease Pencil vertex paint");
1991 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
1992 RNA_def_property_update(
1993 prop, NC_GPENCIL | ND_DATA | ND_GPENCIL_EDITMODE, "rna_GPencil_editmode_update");
1994
1995 prop = RNA_def_property(srna, "use_onion_skinning", PROP_BOOLEAN, PROP_NONE);
1996 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_SHOW_ONIONSKINS);
1997 RNA_def_property_boolean_default(prop, true);
1998 RNA_def_property_ui_text(
1999 prop, "Onion Skins", "Show ghosts of the keyframes before and after the current frame");
2000 RNA_def_property_update(
2001 prop, NC_SCREEN | NC_SCENE | ND_TOOLSETTINGS | ND_DATA | NC_GPENCIL, "rna_GPencil_update");
2002
2003 prop = RNA_def_property(srna, "stroke_thickness_space", PROP_ENUM, PROP_NONE); /* as an enum */
2004 RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
2005 RNA_def_property_enum_items(prop, stroke_thickness_items);
2006 RNA_def_property_ui_text(
2007 prop, "Stroke Thickness", "Set stroke thickness in screen space or world space");
2008 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
2009
2010 prop = RNA_def_property(srna, "pixel_factor", PROP_FLOAT, PROP_NONE);
2011 RNA_def_property_float_sdna(prop, NULL, "pixfactor");
2012 RNA_def_property_range(prop, 0.1f, 30.0f);
2013 RNA_def_property_ui_range(prop, 0.1f, 30.0f, 1, 2);
2014 RNA_def_property_ui_text(
2015 prop,
2016 "Scale",
2017 "Scale conversion factor for pixel size (use larger values for thicker lines)");
2018 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
2019
2020 prop = RNA_def_property(srna, "use_multiedit", PROP_BOOLEAN, PROP_NONE);
2021 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_STROKE_MULTIEDIT);
2022 RNA_def_property_ui_text(prop,
2023 "MultiFrame",
2024 "Edit strokes from multiple grease pencil keyframes at the same time "
2025 "(keyframes must be selected to be included)");
2026 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
2027
2028 prop = RNA_def_property(srna, "use_autolock_layers", PROP_BOOLEAN, PROP_NONE);
2029 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_AUTOLOCK_LAYERS);
2030 RNA_def_property_ui_text(
2031 prop,
2032 "Autolock Layers",
2033 "Lock automatically all layers except active one to avoid accidental changes");
2034 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_autolock");
2035
2036 prop = RNA_def_property(srna, "edit_line_color", PROP_FLOAT, PROP_COLOR_GAMMA);
2037 RNA_def_property_float_sdna(prop, NULL, "line_color");
2038 RNA_def_property_array(prop, 4);
2039 RNA_def_property_range(prop, 0.0f, 1.0f);
2040 RNA_def_property_float_array_default(prop, default_1);
2041 RNA_def_property_ui_text(prop, "Edit Line Color", "Color for editing line");
2042 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
2043
2044 /* onion skinning */
2045 prop = RNA_def_property(srna, "ghost_before_range", PROP_INT, PROP_NONE);
2046 RNA_def_property_int_sdna(prop, NULL, "gstep");
2047 RNA_def_property_range(prop, 0, 120);
2048 RNA_def_property_int_default(prop, 1);
2049 RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
2050 RNA_def_property_ui_text(prop,
2051 "Frames Before",
2052 "Maximum number of frames to show before current frame "
2053 "(0 = don't show any frames before current)");
2054 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
2055
2056 prop = RNA_def_property(srna, "ghost_after_range", PROP_INT, PROP_NONE);
2057 RNA_def_property_int_sdna(prop, NULL, "gstep_next");
2058 RNA_def_property_range(prop, 0, 120);
2059 RNA_def_property_int_default(prop, 1);
2060 RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
2061 RNA_def_property_ui_text(prop,
2062 "Frames After",
2063 "Maximum number of frames to show after current frame "
2064 "(0 = don't show any frames after current)");
2065 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
2066
2067 prop = RNA_def_property(srna, "use_ghost_custom_colors", PROP_BOOLEAN, PROP_NONE);
2068 RNA_def_property_boolean_sdna(
2069 prop, NULL, "onion_flag", GP_ONION_GHOST_PREVCOL | GP_ONION_GHOST_NEXTCOL);
2070 RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
2071 RNA_def_property_ui_text(prop, "Use Custom Ghost Colors", "Use custom colors for ghost frames");
2072 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
2073
2074 prop = RNA_def_property(srna, "before_color", PROP_FLOAT, PROP_COLOR);
2075 RNA_def_property_float_sdna(prop, NULL, "gcolor_prev");
2076 RNA_def_property_array(prop, 3);
2077 RNA_def_property_range(prop, 0.0f, 1.0f);
2078 RNA_def_property_float_array_default(prop, onion_dft1);
2079 RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
2080 RNA_def_property_ui_text(prop, "Before Color", "Base color for ghosts before the active frame");
2081 RNA_def_property_update(
2082 prop, NC_SCREEN | NC_SCENE | ND_TOOLSETTINGS | ND_DATA | NC_GPENCIL, "rna_GPencil_update");
2083
2084 prop = RNA_def_property(srna, "after_color", PROP_FLOAT, PROP_COLOR);
2085 RNA_def_property_float_sdna(prop, NULL, "gcolor_next");
2086 RNA_def_property_array(prop, 3);
2087 RNA_def_property_range(prop, 0.0f, 1.0f);
2088 RNA_def_property_float_array_default(prop, onion_dft2);
2089 RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
2090 RNA_def_property_ui_text(prop, "After Color", "Base color for ghosts after the active frame");
2091 RNA_def_property_update(
2092 prop, NC_SCREEN | NC_SCENE | ND_TOOLSETTINGS | ND_DATA | NC_GPENCIL, "rna_GPencil_update");
2093
2094 prop = RNA_def_property(srna, "use_ghosts_always", PROP_BOOLEAN, PROP_NONE);
2095 RNA_def_property_boolean_sdna(prop, NULL, "onion_flag", GP_ONION_GHOST_ALWAYS);
2096 RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
2097 RNA_def_property_ui_text(prop,
2098 "Always Show Ghosts",
2099 "Ghosts are shown in renders and animation playback. Useful for "
2100 "special effects (e.g. motion blur)");
2101 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
2102
2103 prop = RNA_def_property(srna, "onion_mode", PROP_ENUM, PROP_NONE);
2104 RNA_def_property_enum_sdna(prop, NULL, "onion_mode");
2105 RNA_def_property_enum_items(prop, rna_enum_gpencil_onion_modes_items);
2106 RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
2107 RNA_def_property_ui_text(prop, "Mode", "Mode to display frames");
2108 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
2109
2110 prop = RNA_def_property(srna, "onion_keyframe_type", PROP_ENUM, PROP_NONE);
2111 RNA_def_property_enum_sdna(prop, NULL, "onion_keytype");
2112 RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
2113 RNA_def_property_enum_items(prop, rna_enum_onion_keyframe_type_items);
2114 RNA_def_property_ui_text(prop, "Filter by Type", "Type of keyframe (for filtering)");
2115 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
2116
2117 prop = RNA_def_property(srna, "use_onion_fade", PROP_BOOLEAN, PROP_NONE);
2118 RNA_def_property_boolean_sdna(prop, NULL, "onion_flag", GP_ONION_FADE);
2119 RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
2120 RNA_def_property_ui_text(
2121 prop, "Fade", "Display onion keyframes with a fade in color transparency");
2122 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
2123
2124 prop = RNA_def_property(srna, "use_onion_loop", PROP_BOOLEAN, PROP_NONE);
2125 RNA_def_property_boolean_sdna(prop, NULL, "onion_flag", GP_ONION_LOOP);
2126 RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
2127 RNA_def_property_ui_text(
2128 prop, "Show Start Frame", "Display onion keyframes for looping animations");
2129 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
2130
2131 prop = RNA_def_property(srna, "onion_factor", PROP_FLOAT, PROP_NONE);
2132 RNA_def_property_float_sdna(prop, NULL, "onion_factor");
2133 RNA_def_property_float_default(prop, 0.5f);
2134 RNA_def_property_range(prop, 0.0, 1.0f);
2135 RNA_def_parameter_clear_flags(prop, PROP_ANIMATABLE, 0);
2136 RNA_def_property_ui_text(prop, "Onion Opacity", "Change fade opacity of displayed onion frames");
2137 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
2138
2139 prop = RNA_def_property(srna, "zdepth_offset", PROP_FLOAT, PROP_NONE);
2140 RNA_def_property_float_sdna(prop, NULL, "zdepth_offset");
2141 RNA_def_property_range(prop, 0.0f, 1.0f);
2142 RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1f, 3);
2143 RNA_def_property_float_default(prop, 0.150f);
2144 RNA_def_property_ui_text(prop, "Surface Offset", "Offset amount when drawing in surface mode");
2145 RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
2146
2147 prop = RNA_def_property(srna, "is_annotation", PROP_BOOLEAN, PROP_NONE);
2148 RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_DATA_ANNOTATIONS);
2149 RNA_def_property_clear_flag(prop, PROP_EDITABLE);
2150 RNA_def_property_ui_text(prop, "Annotation", "Current datablock is an annotation");
2151
2152 /* Nested Structs */
2153 prop = RNA_def_property(srna, "grid", PROP_POINTER, PROP_NONE);
2154 RNA_def_property_flag(prop, PROP_NEVER_NULL);
2155 RNA_def_property_struct_type(prop, "GreasePencilGrid");
2156 RNA_def_property_ui_text(
2157 prop, "Grid Settings", "Settings for grid and canvas in the 3D viewport");
2158
2159 rna_def_gpencil_grid(brna);
2160
2161 /* API Functions */
2162 func = RNA_def_function(srna, "clear", "rna_GPencil_clear");
2163 RNA_def_function_ui_description(func, "Remove all the Grease Pencil data");
2164 }
2165
2166 /* --- */
2167
RNA_def_gpencil(BlenderRNA * brna)2168 void RNA_def_gpencil(BlenderRNA *brna)
2169 {
2170 rna_def_gpencil_data(brna);
2171
2172 rna_def_gpencil_layer(brna);
2173 rna_def_gpencil_layer_mask(brna);
2174 rna_def_gpencil_frame(brna);
2175
2176 rna_def_gpencil_stroke(brna);
2177 rna_def_gpencil_stroke_point(brna);
2178 rna_def_gpencil_triangle(brna);
2179
2180 rna_def_gpencil_mvert_group(brna);
2181 }
2182
2183 #endif
2184