Blender  V3.3
gpencil.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2008 Blender Foundation. */
3 
8 #include <math.h>
9 #include <stddef.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 
14 #include "CLG_log.h"
15 
16 #include "MEM_guardedalloc.h"
17 
18 #include "BLI_blenlib.h"
19 #include "BLI_math_vector.h"
20 #include "BLI_string_utils.h"
21 
22 #include "BLT_translation.h"
23 
24 #include "IMB_imbuf.h"
25 #include "IMB_imbuf_types.h"
26 
27 /* Allow using deprecated functionality for .blend file I/O. */
28 #define DNA_DEPRECATED_ALLOW
29 
30 #include "DNA_gpencil_types.h"
31 #include "DNA_material_types.h"
32 #include "DNA_meshdata_types.h"
33 #include "DNA_space_types.h"
34 
35 #include "BKE_action.h"
36 #include "BKE_anim_data.h"
37 #include "BKE_collection.h"
38 #include "BKE_colortools.h"
39 #include "BKE_deform.h"
40 #include "BKE_gpencil.h"
41 #include "BKE_gpencil_geom.h"
43 #include "BKE_icons.h"
44 #include "BKE_idtype.h"
45 #include "BKE_image.h"
46 #include "BKE_lib_id.h"
47 #include "BKE_lib_query.h"
48 #include "BKE_main.h"
49 #include "BKE_material.h"
50 #include "BKE_paint.h"
51 
52 #include "BLI_math_color.h"
53 
54 #include "DEG_depsgraph_query.h"
55 
56 #include "BLO_read_write.h"
57 
58 static CLG_LogRef LOG = {"bke.gpencil"};
59 
60 static void greasepencil_copy_data(Main *UNUSED(bmain),
61  ID *id_dst,
62  const ID *id_src,
63  const int UNUSED(flag))
64 {
65  bGPdata *gpd_dst = (bGPdata *)id_dst;
66  const bGPdata *gpd_src = (const bGPdata *)id_src;
67 
68  /* duplicate material array */
69  if (gpd_src->mat) {
70  gpd_dst->mat = MEM_dupallocN(gpd_src->mat);
71  }
72 
74 
75  /* copy layers */
76  BLI_listbase_clear(&gpd_dst->layers);
77  LISTBASE_FOREACH (bGPDlayer *, gpl_src, &gpd_src->layers) {
78  /* make a copy of source layer and its data */
79 
80  /* TODO: here too could add unused flags... */
81  bGPDlayer *gpl_dst = BKE_gpencil_layer_duplicate(gpl_src, true, true);
82 
83  /* Apply local layer transform to all frames. Calc the active frame is not enough
84  * because onion skin can use more frames. This is more slow but required here. */
85  if (gpl_dst->actframe != NULL) {
86  bool transformed = ((!is_zero_v3(gpl_dst->location)) || (!is_zero_v3(gpl_dst->rotation)) ||
87  (!is_one_v3(gpl_dst->scale)));
88  if (transformed) {
90  gpl_dst->layer_mat, gpl_dst->location, gpl_dst->rotation, gpl_dst->scale);
91  bool do_onion = ((gpl_dst->onion_flag & GP_LAYER_ONIONSKIN) != 0);
92  bGPDframe *init_gpf = (do_onion) ? gpl_dst->frames.first : gpl_dst->actframe;
93  for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
94  LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
95  bGPDspoint *pt;
96  int i;
97  for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
98  mul_m4_v3(gpl_dst->layer_mat, &pt->x);
99  }
100  }
101  /* if not onion, exit loop. */
102  if (!do_onion) {
103  break;
104  }
105  }
106  }
107  }
108 
109  BLI_addtail(&gpd_dst->layers, gpl_dst);
110  }
111 }
112 
113 static void greasepencil_free_data(ID *id)
114 {
115  /* Really not ideal, but for now will do... In theory custom behaviors like not freeing cache
116  * should be handled through specific API, and not be part of the generic one. */
117  BKE_gpencil_free_data((bGPdata *)id, true);
118 }
119 
121 {
122  bGPdata *gpencil = (bGPdata *)id;
123  /* materials */
124  for (int i = 0; i < gpencil->totcol; i++) {
126  }
127 
128  LISTBASE_FOREACH (bGPDlayer *, gplayer, &gpencil->layers) {
130  }
131 }
132 
133 static void greasepencil_blend_write(BlendWriter *writer, ID *id, const void *id_address)
134 {
135  bGPdata *gpd = (bGPdata *)id;
136 
137  /* Clean up, important in undo case to reduce false detection of changed data-blocks. */
138  /* XXX not sure why the whole run-time data is not cleared in reading code,
139  * for now mimicking it here. */
140  gpd->runtime.sbuffer = NULL;
141  gpd->runtime.sbuffer_used = 0;
142  gpd->runtime.sbuffer_size = 0;
143  gpd->runtime.tot_cp_points = 0;
144  gpd->runtime.update_cache = NULL;
145 
146  /* write gpd data block to file */
147  BLO_write_id_struct(writer, bGPdata, id_address, &gpd->id);
148  BKE_id_blend_write(writer, &gpd->id);
149 
150  if (gpd->adt) {
151  BKE_animdata_blend_write(writer, gpd->adt);
152  }
153 
155 
156  BLO_write_pointer_array(writer, gpd->totcol, gpd->mat);
157 
158  /* write grease-pencil layers to file */
159  BLO_write_struct_list(writer, bGPDlayer, &gpd->layers);
160  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
161  /* Write mask list. */
162  BLO_write_struct_list(writer, bGPDlayer_Mask, &gpl->mask_layers);
163  /* write this layer's frames to file */
164  BLO_write_struct_list(writer, bGPDframe, &gpl->frames);
165  LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
166  /* write strokes */
167  BLO_write_struct_list(writer, bGPDstroke, &gpf->strokes);
168  LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
169  BLO_write_struct_array(writer, bGPDspoint, gps->totpoints, gps->points);
170  BLO_write_struct_array(writer, bGPDtriangle, gps->tot_triangles, gps->triangles);
171  BKE_defvert_blend_write(writer, gps->totpoints, gps->dvert);
172  if (gps->editcurve != NULL) {
173  bGPDcurve *gpc = gps->editcurve;
174  BLO_write_struct(writer, bGPDcurve, gpc);
176  writer, bGPDcurve_point, gpc->tot_curve_points, gpc->curve_points);
177  }
178  }
179  }
180  }
181 }
182 
184 {
185  /* We must firstly have some grease-pencil data to link! */
186  if (gpd == NULL) {
187  return;
188  }
189 
190  /* Relink anim-data. */
191  BLO_read_data_address(reader, &gpd->adt);
192  BKE_animdata_blend_read_data(reader, gpd->adt);
193 
194  /* Ensure full objectmode for linked grease pencil. */
195  if (ID_IS_LINKED(gpd)) {
197  gpd->flag &= ~GP_DATA_STROKE_EDITMODE;
201  }
202 
203  /* init stroke buffer */
204  gpd->runtime.sbuffer = NULL;
205  gpd->runtime.sbuffer_used = 0;
206  gpd->runtime.sbuffer_size = 0;
207  gpd->runtime.tot_cp_points = 0;
208  gpd->runtime.update_cache = NULL;
209 
210  /* Relink palettes (old palettes deprecated, only to convert old files). */
211  BLO_read_list(reader, &gpd->palettes);
212  if (gpd->palettes.first != NULL) {
213  LISTBASE_FOREACH (bGPDpalette *, palette, &gpd->palettes) {
214  BLO_read_list(reader, &palette->colors);
215  }
216  }
217 
218  BLO_read_list(reader, &gpd->vertex_group_names);
219 
220  /* Materials. */
221  BLO_read_pointer_array(reader, (void **)&gpd->mat);
222 
223  /* Relink layers. */
224  BLO_read_list(reader, &gpd->layers);
225 
226  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
227  /* Relink frames. */
228  BLO_read_list(reader, &gpl->frames);
229 
230  BLO_read_data_address(reader, &gpl->actframe);
231 
232  gpl->runtime.icon_id = 0;
233 
234  /* Relink masks. */
235  BLO_read_list(reader, &gpl->mask_layers);
236 
237  LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
238  /* Relink strokes (and their points). */
239  BLO_read_list(reader, &gpf->strokes);
240 
241  LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
242  /* Relink stroke points array. */
243  BLO_read_data_address(reader, &gps->points);
244  /* Relink geometry. */
245  BLO_read_data_address(reader, &gps->triangles);
246 
247  /* Relink stroke edit curve. */
248  BLO_read_data_address(reader, &gps->editcurve);
249  if (gps->editcurve != NULL) {
250  /* Relink curve point array. */
251  BLO_read_data_address(reader, &gps->editcurve->curve_points);
252  }
253 
254  /* Relink weight data. */
255  if (gps->dvert) {
256  BLO_read_data_address(reader, &gps->dvert);
257  BKE_defvert_blend_read(reader, gps->totpoints, gps->dvert);
258  }
259  }
260  }
261  }
262 }
263 
265 {
266  bGPdata *gpd = (bGPdata *)id;
267  BKE_gpencil_blend_read_data(reader, gpd);
268 }
269 
271 {
272  bGPdata *gpd = (bGPdata *)id;
273 
274  /* Relink all data-block linked by GP data-block. */
275  /* Layers */
276  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
277  /* Layer -> Parent References */
278  BLO_read_id_address(reader, gpd->id.lib, &gpl->parent);
279  }
280 
281  /* materials */
282  for (int a = 0; a < gpd->totcol; a++) {
283  BLO_read_id_address(reader, gpd->id.lib, &gpd->mat[a]);
284  }
285 }
286 
288 {
289  bGPdata *gpd = (bGPdata *)id;
290  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
291  BLO_expand(expander, gpl->parent);
292  }
293 
294  for (int a = 0; a < gpd->totcol; a++) {
295  BLO_expand(expander, gpd->mat[a]);
296  }
297 }
298 
300  .id_code = ID_GD,
301  .id_filter = FILTER_ID_GD,
302  .main_listbase_index = INDEX_ID_GD,
303  .struct_size = sizeof(bGPdata),
304  .name = "GPencil",
305  .name_plural = "grease_pencils",
306  .translation_context = BLT_I18NCONTEXT_ID_GPENCIL,
308  .asset_type_info = NULL,
309 
310  .init_data = NULL,
311  .copy_data = greasepencil_copy_data,
312  .free_data = greasepencil_free_data,
313  .make_local = NULL,
314  .foreach_id = greasepencil_foreach_id,
315  .foreach_cache = NULL,
316  .foreach_path = NULL,
317  .owner_get = NULL,
318 
319  .blend_write = greasepencil_blend_write,
320  .blend_read_data = greasepencil_blend_read_data,
321  .blend_read_lib = greasepencil_blend_read_lib,
322  .blend_read_expand = greasepencil_blend_read_expand,
323 
324  .blend_read_undo_preserve = NULL,
325 
326  .lib_override_apply_post = NULL,
327 };
328 
329 /* ************************************************** */
330 /* Draw Engine */
331 
334 
336 {
337  if (gpd) {
340  }
341 }
342 
344 {
345  if (gpd) {
347  }
348 }
349 
350 /* ************************************************** */
351 /* Memory Management */
352 
354 {
355  if (dvert == NULL) {
356  return;
357  }
358  MEM_SAFE_FREE(dvert->dw);
359 }
360 
362 {
363  if (gps == NULL) {
364  return;
365  }
366 
367  if (gps->dvert == NULL) {
368  return;
369  }
370 
371  for (int i = 0; i < gps->totpoints; i++) {
372  MDeformVert *dvert = &gps->dvert[i];
374  }
375 }
376 
378 {
379  if (gps == NULL) {
380  return;
381  }
382  bGPDcurve *editcurve = gps->editcurve;
383  if (editcurve == NULL) {
384  return;
385  }
386  MEM_freeN(editcurve->curve_points);
387  MEM_freeN(editcurve);
388  gps->editcurve = NULL;
389 }
390 
392 {
393  if (gps == NULL) {
394  return;
395  }
396  /* free stroke memory arrays, then stroke itself */
397  if (gps->points) {
398  MEM_freeN(gps->points);
399  }
400  if (gps->dvert) {
402  MEM_freeN(gps->dvert);
403  }
404  if (gps->triangles) {
405  MEM_freeN(gps->triangles);
406  }
407  if (gps->editcurve != NULL) {
409  }
410 
411  MEM_freeN(gps);
412 }
413 
415 {
416  bool changed = (BLI_listbase_is_empty(&gpf->strokes) == false);
417 
418  /* free strokes */
421  }
423 
424  return changed;
425 }
426 
428 {
429  bGPDframe *gpf_next;
430 
431  /* error checking */
432  if (gpl == NULL) {
433  return;
434  }
435 
436  /* free frames */
437  for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf_next) {
438  gpf_next = gpf->next;
439 
440  /* free strokes and their associated memory */
442  BLI_freelinkN(&gpl->frames, gpf);
443  }
444  gpl->actframe = NULL;
445 }
446 
448 {
449  /* Free masks. */
450  bGPDlayer_Mask *mask_next = NULL;
451  for (bGPDlayer_Mask *mask = gpl->mask_layers.first; mask; mask = mask_next) {
452  mask_next = mask->next;
454  }
455 }
457 {
458  bGPDlayer *gpl_next;
459 
460  /* error checking */
461  if (list == NULL) {
462  return;
463  }
464 
465  /* delete layers */
466  for (bGPDlayer *gpl = list->first; gpl; gpl = gpl_next) {
467  gpl_next = gpl->next;
468 
469  /* free layers and their data */
471 
472  /* Free masks. */
474 
475  BLI_freelinkN(list, gpl);
476  }
477 }
478 
479 void BKE_gpencil_free_data(bGPdata *gpd, bool free_all)
480 {
481  /* free layers */
483 
484  /* materials */
485  MEM_SAFE_FREE(gpd->mat);
486 
488 
490 
491  /* free all data */
492  if (free_all) {
493  /* clear cache */
495  }
496 }
497 
499 {
500  BKE_gpencil_free_data(gpd_eval, true);
501  BKE_libblock_free_data(&gpd_eval->id, false);
502  BLI_assert(!gpd_eval->id.py_instance); /* Or call #BKE_libblock_free_data_py. */
503  MEM_freeN(gpd_eval);
504 }
505 
507 {
509 }
510 
511 /* ************************************************** */
512 /* Container Creation */
513 
515 {
516  bGPDframe *gpf = NULL, *gf = NULL;
517  short state = 0;
518 
519  /* error checking */
520  if (gpl == NULL) {
521  return NULL;
522  }
523 
524  /* allocate memory for this frame */
525  gpf = MEM_callocN(sizeof(bGPDframe), "bGPDframe");
526  gpf->framenum = cframe;
527 
528  /* find appropriate place to add frame */
529  if (gpl->frames.first) {
530  for (gf = gpl->frames.first; gf; gf = gf->next) {
531  /* check if frame matches one that is supposed to be added */
532  if (gf->framenum == cframe) {
533  state = -1;
534  break;
535  }
536 
537  /* if current frame has already exceeded the frame to add, add before */
538  if (gf->framenum > cframe) {
539  BLI_insertlinkbefore(&gpl->frames, gf, gpf);
540  state = 1;
541  break;
542  }
543  }
544  }
545 
546  /* check whether frame was added successfully */
547  if (state == -1) {
548  CLOG_ERROR(
549  &LOG, "Frame (%d) existed already for this layer_active. Using existing frame", cframe);
550 
551  /* free the newly created one, and use the old one instead */
552  MEM_freeN(gpf);
553 
554  /* return existing frame instead... */
555  BLI_assert(gf != NULL);
556  gpf = gf;
557  }
558  else if (state == 0) {
559  /* add to end then! */
560  BLI_addtail(&gpl->frames, gpf);
561  }
562 
563  /* return frame */
564  return gpf;
565 }
566 
568 {
569  bGPDframe *new_frame;
570  bool found = false;
571 
572  /* Error checking/handling */
573  if (gpl == NULL) {
574  /* no layer */
575  return NULL;
576  }
577  if (gpl->actframe == NULL) {
578  /* no active frame, so just create a new one from scratch */
579  return BKE_gpencil_frame_addnew(gpl, cframe);
580  }
581 
582  /* Create a copy of the frame */
583  new_frame = BKE_gpencil_frame_duplicate(gpl->actframe, true);
584 
585  /* Find frame to insert it before */
586  LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
587  if (gpf->framenum > cframe) {
588  /* Add it here */
589  BLI_insertlinkbefore(&gpl->frames, gpf, new_frame);
590 
591  found = true;
592  break;
593  }
594  if (gpf->framenum == cframe) {
595  /* This only happens when we're editing with framelock on...
596  * - Delete the new frame and don't do anything else here...
597  */
598  BKE_gpencil_free_strokes(new_frame);
599  MEM_freeN(new_frame);
600  new_frame = NULL;
601 
602  found = true;
603  break;
604  }
605  }
606 
607  if (found == false) {
608  /* Add new frame to the end */
609  BLI_addtail(&gpl->frames, new_frame);
610  }
611 
612  /* Ensure that frame is set up correctly, and return it */
613  if (new_frame) {
614  new_frame->framenum = cframe;
615  gpl->actframe = new_frame;
616  }
617 
618  return new_frame;
619 }
620 
622  const char *name,
623  const bool setactive,
624  const bool add_to_header)
625 {
626  bGPDlayer *gpl = NULL;
627  bGPDlayer *gpl_active = NULL;
628 
629  /* check that list is ok */
630  if (gpd == NULL) {
631  return NULL;
632  }
633 
634  /* allocate memory for frame and add to end of list */
635  gpl = MEM_callocN(sizeof(bGPDlayer), "bGPDlayer");
636 
637  gpl_active = BKE_gpencil_layer_active_get(gpd);
638 
639  /* Add to data-block. */
640  if (add_to_header) {
641  BLI_addhead(&gpd->layers, gpl);
642  }
643  else {
644  if (gpl_active == NULL) {
645  BLI_addtail(&gpd->layers, gpl);
646  }
647  else {
648  /* if active layer, add after that layer */
649  BLI_insertlinkafter(&gpd->layers, gpl_active, gpl);
650  }
651  }
652  /* annotation vs GP Object behavior is slightly different */
653  if (gpd->flag & GP_DATA_ANNOTATIONS) {
654  /* set default color of new strokes for this layer */
655  copy_v4_v4(gpl->color, U.gpencil_new_layer_col);
656  gpl->opacity = 1.0f;
657 
658  /* set default thickness of new strokes for this layer */
659  gpl->thickness = 3;
660 
661  /* Onion colors */
662  ARRAY_SET_ITEMS(gpl->gcolor_prev, 0.302f, 0.851f, 0.302f);
663  ARRAY_SET_ITEMS(gpl->gcolor_next, 0.250f, 0.1f, 1.0f);
664  }
665  else {
666  /* thickness parameter represents "thickness change", not absolute thickness */
667  gpl->thickness = 0;
668  gpl->opacity = 1.0f;
669  /* default channel color */
670  ARRAY_SET_ITEMS(gpl->color, 0.2f, 0.2f, 0.2f);
671  /* Default vertex mix. */
672  gpl->vertex_paint_opacity = 1.0f;
673  /* Enable onion skin. */
675  }
676 
677  /* auto-name */
678  BLI_strncpy(gpl->info, DATA_(name), sizeof(gpl->info));
679  BLI_uniquename(&gpd->layers,
680  gpl,
681  (gpd->flag & GP_DATA_ANNOTATIONS) ? DATA_("Note") : DATA_("GP_Layer"),
682  '.',
683  offsetof(bGPDlayer, info),
684  sizeof(gpl->info));
685 
686  /* Enable always affected by scene lights. */
687  gpl->flag |= GP_LAYER_USE_LIGHTS;
688 
689  /* Init transform. */
690  zero_v3(gpl->location);
691  zero_v3(gpl->rotation);
692  copy_v3_fl(gpl->scale, 1.0f);
693  loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
694  invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
695 
696  /* make this one the active one */
697  if (setactive) {
699  }
700 
701  /* return layer */
702  return gpl;
703 }
704 
705 bGPdata *BKE_gpencil_data_addnew(Main *bmain, const char name[])
706 {
707  bGPdata *gpd;
708 
709  /* allocate memory for a new block */
710  gpd = BKE_libblock_alloc(bmain, ID_GD, name, 0);
711 
712  /* initial settings */
714 
715  /* general flags */
716  gpd->flag |= GP_DATA_VIEWALIGN;
717  /* always enable object onion skin switch */
719  /* GP object specific settings */
720  ARRAY_SET_ITEMS(gpd->line_color, 0.6f, 0.6f, 0.6f, 0.5f);
721 
723 
727 
728  /* use adaptive curve resolution by default */
730 
731  gpd->zdepth_offset = 0.150f;
732 
733  /* grid settings */
734  ARRAY_SET_ITEMS(gpd->grid.color, 0.5f, 0.5f, 0.5f); /* Color */
735  ARRAY_SET_ITEMS(gpd->grid.scale, 1.0f, 1.0f); /* Scale */
736  gpd->grid.lines = GP_DEFAULT_GRID_LINES; /* Number of lines */
737 
738  /* Onion-skinning settings (data-block level) */
739  gpd->onion_keytype = -1; /* All by default. */
741  gpd->onion_flag |= GP_ONION_FADE;
743  gpd->onion_factor = 0.5f;
744  ARRAY_SET_ITEMS(gpd->gcolor_prev, 0.145098f, 0.419608f, 0.137255f); /* green */
745  ARRAY_SET_ITEMS(gpd->gcolor_next, 0.125490f, 0.082353f, 0.529412f); /* blue */
746  gpd->gstep = 1;
747  gpd->gstep_next = 1;
748 
749  return gpd;
750 }
751 
752 /* ************************************************** */
753 /* Primitive Creation */
754 /* Utilities for easier bulk-creation of geometry */
755 
756 bGPDstroke *BKE_gpencil_stroke_new(int mat_idx, int totpoints, short thickness)
757 {
758  /* allocate memory for a new stroke */
759  bGPDstroke *gps = MEM_callocN(sizeof(bGPDstroke), "gp_stroke");
760 
761  gps->thickness = thickness;
762  gps->fill_opacity_fac = 1.0f;
763  gps->hardeness = 1.0f;
764  copy_v2_fl(gps->aspect_ratio, 1.0f);
765 
766  gps->uv_scale = 1.0f;
767 
768  gps->inittime = 0;
769 
770  gps->flag = GP_STROKE_3DSPACE;
771 
772  gps->totpoints = totpoints;
773  if (gps->totpoints > 0) {
774  gps->points = MEM_callocN(sizeof(bGPDspoint) * gps->totpoints, "gp_stroke_points");
775  }
776  else {
777  gps->points = NULL;
778  }
779 
780  /* initialize triangle memory to dummy data */
781  gps->triangles = NULL;
782  gps->tot_triangles = 0;
783 
784  gps->mat_nr = mat_idx;
785 
786  gps->dvert = NULL;
787  gps->editcurve = NULL;
788 
789  return gps;
790 }
791 
793  bGPDframe *gpf, int mat_idx, int totpoints, short thickness, const bool insert_at_head)
794 {
795  bGPDstroke *gps = BKE_gpencil_stroke_new(mat_idx, totpoints, thickness);
796 
797  /* Add to frame. */
798  if ((gps != NULL) && (gpf != NULL)) {
799  if (!insert_at_head) {
800  BLI_addtail(&gpf->strokes, gps);
801  }
802  else {
803  BLI_addhead(&gpf->strokes, gps);
804  }
805  }
806 
807  return gps;
808 }
809 
811  bGPDframe *gpf, bGPDstroke *existing, int mat_idx, int totpoints, short thickness)
812 {
813  bGPDstroke *gps = BKE_gpencil_stroke_add(gpf, mat_idx, totpoints, thickness, false);
814  /* Copy run-time color data so that strokes added in the modifier has the style.
815  * There are depsgraph reference pointers inside,
816  * change the copy function if interfere with future drawing implementation. */
817  memcpy(&gps->runtime, &existing->runtime, sizeof(bGPDstroke_Runtime));
818  return gps;
819 }
820 
821 bGPDcurve *BKE_gpencil_stroke_editcurve_new(const int tot_curve_points)
822 {
823  bGPDcurve *new_gp_curve = (bGPDcurve *)MEM_callocN(sizeof(bGPDcurve), __func__);
824  new_gp_curve->tot_curve_points = tot_curve_points;
825  new_gp_curve->curve_points = (bGPDcurve_point *)MEM_callocN(
826  sizeof(bGPDcurve_point) * tot_curve_points, __func__);
827 
828  return new_gp_curve;
829 }
830 
831 /* ************************************************** */
832 /* Data Duplication */
833 
835 {
836  if (gps_src == NULL) {
837  return;
838  }
839  BLI_assert(gps_src->totpoints == gps_dst->totpoints);
840 
841  BKE_defvert_array_copy(gps_dst->dvert, gps_src->dvert, gps_src->totpoints);
842 }
843 
845 {
846  bGPDcurve *gpc_dst = MEM_dupallocN(gpc_src);
847 
848  if (gpc_src->curve_points != NULL) {
849  gpc_dst->curve_points = MEM_dupallocN(gpc_src->curve_points);
850  }
851 
852  return gpc_dst;
853 }
854 
856  const bool dup_points,
857  const bool dup_curve)
858 {
859  bGPDstroke *gps_dst = NULL;
860 
861  gps_dst = MEM_dupallocN(gps_src);
862  gps_dst->prev = gps_dst->next = NULL;
863  gps_dst->triangles = MEM_dupallocN(gps_src->triangles);
864 
865  if (dup_points) {
866  gps_dst->points = MEM_dupallocN(gps_src->points);
867 
868  if (gps_src->dvert != NULL) {
869  gps_dst->dvert = MEM_dupallocN(gps_src->dvert);
870  BKE_gpencil_stroke_weights_duplicate(gps_src, gps_dst);
871  }
872  else {
873  gps_dst->dvert = NULL;
874  }
875  }
876  else {
877  gps_dst->points = NULL;
878  gps_dst->dvert = NULL;
879  }
880 
881  if (dup_curve && gps_src->editcurve != NULL) {
883  }
884  else {
885  gps_dst->editcurve = NULL;
886  }
887 
888  /* return new stroke */
889  return gps_dst;
890 }
891 
892 bGPDframe *BKE_gpencil_frame_duplicate(const bGPDframe *gpf_src, const bool dup_strokes)
893 {
894  bGPDstroke *gps_dst = NULL;
895  bGPDframe *gpf_dst;
896 
897  /* error checking */
898  if (gpf_src == NULL) {
899  return NULL;
900  }
901 
902  /* make a copy of the source frame */
903  gpf_dst = MEM_dupallocN(gpf_src);
904  gpf_dst->prev = gpf_dst->next = NULL;
905 
906  /* Copy strokes. */
907  BLI_listbase_clear(&gpf_dst->strokes);
908  if (dup_strokes) {
909  LISTBASE_FOREACH (bGPDstroke *, gps_src, &gpf_src->strokes) {
910  /* make copy of source stroke */
911  gps_dst = BKE_gpencil_stroke_duplicate(gps_src, true, true);
912  BLI_addtail(&gpf_dst->strokes, gps_dst);
913  }
914  }
915 
916  /* return new frame */
917  return gpf_dst;
918 }
919 
920 void BKE_gpencil_frame_copy_strokes(bGPDframe *gpf_src, struct bGPDframe *gpf_dst)
921 {
922  bGPDstroke *gps_dst = NULL;
923  /* error checking */
924  if ((gpf_src == NULL) || (gpf_dst == NULL)) {
925  return;
926  }
927 
928  /* copy strokes */
929  BLI_listbase_clear(&gpf_dst->strokes);
930  LISTBASE_FOREACH (bGPDstroke *, gps_src, &gpf_src->strokes) {
931  /* make copy of source stroke */
932  gps_dst = BKE_gpencil_stroke_duplicate(gps_src, true, true);
933  BLI_addtail(&gpf_dst->strokes, gps_dst);
934  }
935 }
936 
938  const bool dup_frames,
939  const bool dup_strokes)
940 {
941  bGPDframe *gpf_dst;
942  bGPDlayer *gpl_dst;
943 
944  /* error checking */
945  if (gpl_src == NULL) {
946  return NULL;
947  }
948 
949  /* make a copy of source layer */
950  gpl_dst = MEM_dupallocN(gpl_src);
951  gpl_dst->prev = gpl_dst->next = NULL;
952 
953  /* Copy masks. */
954  BKE_gpencil_layer_mask_copy(gpl_src, gpl_dst);
955 
956  /* copy frames */
957  BLI_listbase_clear(&gpl_dst->frames);
958  if (dup_frames) {
959  LISTBASE_FOREACH (bGPDframe *, gpf_src, &gpl_src->frames) {
960  /* make a copy of source frame */
961  gpf_dst = BKE_gpencil_frame_duplicate(gpf_src, dup_strokes);
962  BLI_addtail(&gpl_dst->frames, gpf_dst);
963 
964  /* if source frame was the current layer's 'active' frame, reassign that too */
965  if (gpf_src == gpl_dst->actframe) {
966  gpl_dst->actframe = gpf_dst;
967  }
968  }
969  }
970 
971  /* return new layer */
972  return gpl_dst;
973 }
974 
975 void BKE_gpencil_data_copy_settings(const bGPdata *gpd_src, bGPdata *gpd_dst)
976 {
977  gpd_dst->flag = gpd_src->flag;
978  gpd_dst->curve_edit_resolution = gpd_src->curve_edit_resolution;
979  gpd_dst->curve_edit_threshold = gpd_src->curve_edit_threshold;
981  gpd_dst->pixfactor = gpd_src->pixfactor;
982  copy_v4_v4(gpd_dst->line_color, gpd_src->line_color);
983 
984  gpd_dst->onion_factor = gpd_src->onion_factor;
985  gpd_dst->onion_mode = gpd_src->onion_mode;
986  gpd_dst->onion_flag = gpd_src->onion_flag;
987  gpd_dst->gstep = gpd_src->gstep;
988  gpd_dst->gstep_next = gpd_src->gstep_next;
989 
990  copy_v3_v3(gpd_dst->gcolor_prev, gpd_src->gcolor_prev);
991  copy_v3_v3(gpd_dst->gcolor_next, gpd_src->gcolor_next);
992 
993  gpd_dst->zdepth_offset = gpd_src->zdepth_offset;
994 
995  gpd_dst->totlayer = gpd_src->totlayer;
996  gpd_dst->totframe = gpd_src->totframe;
997  gpd_dst->totstroke = gpd_src->totstroke;
998  gpd_dst->totpoint = gpd_src->totpoint;
999 
1000  gpd_dst->draw_mode = gpd_src->draw_mode;
1001  gpd_dst->onion_keytype = gpd_src->onion_keytype;
1002 
1003  gpd_dst->select_last_index = gpd_src->select_last_index;
1005 
1006  copy_v3_v3(gpd_dst->grid.color, gpd_src->grid.color);
1007  copy_v2_v2(gpd_dst->grid.scale, gpd_src->grid.scale);
1008  copy_v2_v2(gpd_dst->grid.offset, gpd_src->grid.offset);
1009  gpd_dst->grid.lines = gpd_src->grid.lines;
1010 }
1011 
1013 {
1014  gpl_dst->line_change = gpl_src->line_change;
1015  copy_v4_v4(gpl_dst->tintcolor, gpl_src->tintcolor);
1016  gpl_dst->opacity = gpl_src->opacity;
1017  gpl_dst->vertex_paint_opacity = gpl_src->vertex_paint_opacity;
1018  gpl_dst->pass_index = gpl_src->pass_index;
1019  gpl_dst->parent = gpl_src->parent;
1020  copy_m4_m4(gpl_dst->inverse, gpl_src->inverse);
1021  BLI_strncpy(gpl_dst->parsubstr, gpl_src->parsubstr, 64);
1022  gpl_dst->partype = gpl_src->partype;
1023  BLI_strncpy(gpl_dst->viewlayername, gpl_src->viewlayername, 64);
1024  copy_v3_v3(gpl_dst->location, gpl_src->location);
1025  copy_v3_v3(gpl_dst->rotation, gpl_src->rotation);
1026  copy_v3_v3(gpl_dst->scale, gpl_src->scale);
1027  copy_m4_m4(gpl_dst->layer_mat, gpl_src->layer_mat);
1028  copy_m4_m4(gpl_dst->layer_invmat, gpl_src->layer_invmat);
1029  gpl_dst->blend_mode = gpl_src->blend_mode;
1030  gpl_dst->flag = gpl_src->flag;
1031  gpl_dst->onion_flag = gpl_src->onion_flag;
1032 }
1033 
1035 {
1036  gpf_dst->flag = gpf_src->flag;
1037  gpf_dst->key_type = gpf_src->key_type;
1038  gpf_dst->framenum = gpf_src->framenum;
1039 }
1040 
1042 {
1043  gps_dst->thickness = gps_src->thickness;
1044  gps_dst->flag = gps_src->flag;
1045  gps_dst->inittime = gps_src->inittime;
1046  gps_dst->mat_nr = gps_src->mat_nr;
1047  copy_v2_v2_short(gps_dst->caps, gps_src->caps);
1048  gps_dst->hardeness = gps_src->hardeness;
1049  copy_v2_v2(gps_dst->aspect_ratio, gps_src->aspect_ratio);
1050  gps_dst->fill_opacity_fac = gps_dst->fill_opacity_fac;
1051  copy_v3_v3(gps_dst->boundbox_min, gps_src->boundbox_min);
1052  copy_v3_v3(gps_dst->boundbox_max, gps_src->boundbox_max);
1053  gps_dst->uv_rotation = gps_src->uv_rotation;
1054  copy_v2_v2(gps_dst->uv_translation, gps_src->uv_translation);
1055  gps_dst->uv_scale = gps_src->uv_scale;
1056  gps_dst->select_index = gps_src->select_index;
1057  copy_v4_v4(gps_dst->vert_color_fill, gps_src->vert_color_fill);
1058 }
1059 
1060 bGPdata *BKE_gpencil_data_duplicate(Main *bmain, const bGPdata *gpd_src, bool internal_copy)
1061 {
1062  bGPdata *gpd_dst;
1063 
1064  /* Yuck and super-uber-hyper yuck!!!
1065  * Should be replaceable with a no-main copy (LIB_ID_COPY_NO_MAIN etc.), but not sure about it,
1066  * so for now keep old code for that one. */
1067 
1068  /* error checking */
1069  if (gpd_src == NULL) {
1070  return NULL;
1071  }
1072 
1073  if (internal_copy) {
1074  /* make a straight copy for undo buffers used during stroke drawing */
1075  gpd_dst = MEM_dupallocN(gpd_src);
1076  }
1077  else {
1078  BLI_assert(bmain != NULL);
1079  gpd_dst = (bGPdata *)BKE_id_copy(bmain, &gpd_src->id);
1080  }
1081 
1082  /* Copy internal data (layers, etc.) */
1083  greasepencil_copy_data(bmain, &gpd_dst->id, &gpd_src->id, 0);
1084 
1085  /* return new */
1086  return gpd_dst;
1087 }
1088 
1089 /* ************************************************** */
1090 /* GP Stroke API */
1091 
1093 {
1094  bGPDspoint *pt;
1095  int i;
1096 
1097  /* error checking */
1098  if (gps == NULL) {
1099  return;
1100  }
1101 
1102  /* we'll stop when we find the first selected point,
1103  * so initially, we must deselect
1104  */
1105  gps->flag &= ~GP_STROKE_SELECT;
1107 
1108  for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
1109  if (pt->flag & GP_SPOINT_SELECT) {
1110  gps->flag |= GP_STROKE_SELECT;
1111  break;
1112  }
1113  }
1114 
1115  if (gps->flag & GP_STROKE_SELECT) {
1117  }
1118 }
1119 
1121 {
1122  bGPDcurve *gpc = gps->editcurve;
1123  if (gpc == NULL) {
1124  return;
1125  }
1126 
1127  gps->flag &= ~GP_STROKE_SELECT;
1129  gpc->flag &= ~GP_CURVE_SELECT;
1130 
1131  bool is_selected = false;
1132  for (int i = 0; i < gpc->tot_curve_points; i++) {
1133  bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
1134  BezTriple *bezt = &gpc_pt->bezt;
1135 
1136  if (BEZT_ISSEL_ANY(bezt)) {
1137  gpc_pt->flag |= GP_SPOINT_SELECT;
1138  }
1139  else {
1140  gpc_pt->flag &= ~GP_SPOINT_SELECT;
1141  }
1142 
1143  if (gpc_pt->flag & GP_SPOINT_SELECT) {
1144  is_selected = true;
1145  }
1146  }
1147 
1148  if (is_selected) {
1149  gpc->flag |= GP_CURVE_SELECT;
1150  gps->flag |= GP_STROKE_SELECT;
1152  }
1153 }
1154 
1156 {
1157  gpd->select_last_index++;
1158  gps->select_index = gpd->select_last_index;
1159 }
1160 
1162 {
1163  gps->select_index = 0;
1164 }
1165 
1166 /* ************************************************** */
1167 /* GP Frame API */
1168 
1170 {
1171  bGPDstroke *gps = (gpf) ? gpf->strokes.last : NULL;
1172  int cfra = (gpf) ? gpf->framenum : 0; /* assume that the current frame was not locked */
1173 
1174  /* error checking */
1175  if (ELEM(NULL, gpf, gps)) {
1176  return;
1177  }
1178 
1179  /* free the stroke and its data */
1180  if (gps->points) {
1181  MEM_freeN(gps->points);
1182  }
1183  if (gps->dvert) {
1185  MEM_freeN(gps->dvert);
1186  }
1187  MEM_freeN(gps->triangles);
1188  BLI_freelinkN(&gpf->strokes, gps);
1189 
1190  /* if frame has no strokes after this, delete it */
1191  if (BLI_listbase_is_empty(&gpf->strokes)) {
1194  }
1195 }
1196 
1197 /* ************************************************** */
1198 /* GP Layer API */
1199 
1201 {
1202  /* Sanity check */
1203  if (gpl == NULL) {
1204  return false;
1205  }
1206 
1207  /* Layer must be: Visible + Editable */
1208  if ((gpl->flag & (GP_LAYER_HIDE | GP_LAYER_LOCKED)) == 0) {
1209  return true;
1210  }
1211 
1212  /* Something failed */
1213  return false;
1214 }
1215 
1217 {
1218  bGPDframe *gpf;
1219 
1220  /* Search in reverse order, since this is often used for playback/adding,
1221  * where it's less likely that we're interested in the earlier frames
1222  */
1223  for (gpf = gpl->frames.last; gpf; gpf = gpf->prev) {
1224  if (gpf->framenum == cframe) {
1225  return gpf;
1226  }
1227  }
1228 
1229  return NULL;
1230 }
1231 
1233 {
1234  bGPDframe *gpf = NULL;
1235  bool found = false;
1236 
1237  /* error checking */
1238  if (gpl == NULL) {
1239  return NULL;
1240  }
1241 
1242  /* check if there is already an active frame */
1243  if (gpl->actframe) {
1244  gpf = gpl->actframe;
1245 
1246  /* do not allow any changes to layer's active frame if layer is locked from changes
1247  * or if the layer has been set to stay on the current frame
1248  */
1249  if (gpl->flag & GP_LAYER_FRAMELOCK) {
1250  return gpf;
1251  }
1252  /* do not allow any changes to actframe if frame has painting tag attached to it */
1253  if (gpf->flag & GP_FRAME_PAINT) {
1254  return gpf;
1255  }
1256 
1257  /* try to find matching frame */
1258  if (gpf->framenum < cframe) {
1259  for (; gpf; gpf = gpf->next) {
1260  if (gpf->framenum == cframe) {
1261  found = true;
1262  break;
1263  }
1264  /* If this is the last frame or the next frame is at a later time, we found the right
1265  * frame. */
1266  if (!(gpf->next) || (gpf->next->framenum > cframe)) {
1267  found = true;
1268  break;
1269  }
1270  }
1271 
1272  /* set the appropriate frame */
1273  if (addnew) {
1274  if ((found) && (gpf->framenum == cframe)) {
1275  gpl->actframe = gpf;
1276  }
1277  else if (addnew == GP_GETFRAME_ADD_COPY) {
1278  /* The frame_addcopy function copies the active frame of gpl,
1279  so we need to set the active frame before copying.
1280  */
1281  gpl->actframe = gpf;
1282  gpl->actframe = BKE_gpencil_frame_addcopy(gpl, cframe);
1283  }
1284  else {
1285  gpl->actframe = BKE_gpencil_frame_addnew(gpl, cframe);
1286  }
1287  }
1288  else if (found) {
1289  gpl->actframe = gpf;
1290  }
1291  else {
1292  gpl->actframe = gpl->frames.last;
1293  }
1294  }
1295  else {
1296  for (; gpf; gpf = gpf->prev) {
1297  if (gpf->framenum <= cframe) {
1298  found = true;
1299  break;
1300  }
1301  }
1302 
1303  /* set the appropriate frame */
1304  if (addnew) {
1305  if ((found) && (gpf->framenum == cframe)) {
1306  gpl->actframe = gpf;
1307  }
1308  else if (addnew == GP_GETFRAME_ADD_COPY) {
1309  /* The frame_addcopy function copies the active frame of gpl;
1310  so we need to set the active frame before copying.
1311  */
1312  gpl->actframe = gpf;
1313  gpl->actframe = BKE_gpencil_frame_addcopy(gpl, cframe);
1314  }
1315  else {
1316  gpl->actframe = BKE_gpencil_frame_addnew(gpl, cframe);
1317  }
1318  }
1319  else if (found) {
1320  gpl->actframe = gpf;
1321  }
1322  else {
1323  gpl->actframe = gpl->frames.first;
1324  }
1325  }
1326  }
1327  else if (gpl->frames.first) {
1328  /* check which of the ends to start checking from */
1329  const int first = ((bGPDframe *)(gpl->frames.first))->framenum;
1330  const int last = ((bGPDframe *)(gpl->frames.last))->framenum;
1331 
1332  if (abs(cframe - first) > abs(cframe - last)) {
1333  /* find gp-frame which is less than or equal to cframe */
1334  for (gpf = gpl->frames.last; gpf; gpf = gpf->prev) {
1335  if (gpf->framenum <= cframe) {
1336  found = true;
1337  break;
1338  }
1339  }
1340  }
1341  else {
1342  /* find gp-frame which is less than or equal to cframe */
1343  for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
1344  if (gpf->framenum <= cframe) {
1345  found = true;
1346  break;
1347  }
1348  }
1349  }
1350 
1351  /* set the appropriate frame */
1352  if (addnew) {
1353  if ((found) && (gpf->framenum == cframe)) {
1354  gpl->actframe = gpf;
1355  }
1356  else {
1357  gpl->actframe = BKE_gpencil_frame_addnew(gpl, cframe);
1358  }
1359  }
1360  else if (found) {
1361  gpl->actframe = gpf;
1362  }
1363  else {
1364  /* If delete first frame, need to find one. */
1365  if (gpl->frames.first != NULL) {
1366  gpl->actframe = gpl->frames.first;
1367  }
1368  else {
1369  /* unresolved errogenous situation! */
1370  CLOG_STR_ERROR(&LOG, "cannot find appropriate gp-frame");
1371  /* gpl->actframe should still be NULL */
1372  }
1373  }
1374  }
1375  else {
1376  /* currently no frames (add if allowed to) */
1377  if (addnew) {
1378  gpl->actframe = BKE_gpencil_frame_addnew(gpl, cframe);
1379  }
1380  else {
1381  /* don't do anything... this may be when no frames yet! */
1382  /* gpl->actframe should still be NULL */
1383  }
1384  }
1385 
1386  /* Don't select first frame if greater than current frame. */
1387  if ((gpl->actframe != NULL) && (gpl->actframe == gpl->frames.first) &&
1388  (gpl->actframe->framenum > cframe)) {
1389  gpl->actframe = NULL;
1390  }
1391 
1392  /* return */
1393  return gpl->actframe;
1394 }
1395 
1397 {
1398  bool changed = false;
1399 
1400  /* error checking */
1401  if (ELEM(NULL, gpl, gpf)) {
1402  return false;
1403  }
1404 
1405  /* if this frame was active, make the previous frame active instead
1406  * since it's tricky to set active frame otherwise
1407  */
1408  if (gpl->actframe == gpf) {
1409  gpl->actframe = gpf->prev;
1410  }
1411 
1412  /* free the frame and its data */
1413  changed = BKE_gpencil_free_strokes(gpf);
1414  BLI_freelinkN(&gpl->frames, gpf);
1415 
1416  return changed;
1417 }
1418 
1420 {
1421  if (name[0] == '\0') {
1422  return NULL;
1423  }
1424  return BLI_findstring(&gpd->layers, name, offsetof(bGPDlayer, info));
1425 }
1426 
1428 {
1429  if (name[0] == '\0') {
1430  return NULL;
1431  }
1432  return BLI_findstring(&gpl->mask_layers, name, offsetof(bGPDlayer_Mask, name));
1433 }
1434 
1436 {
1437 
1438  bGPDlayer_Mask *mask = MEM_callocN(sizeof(bGPDlayer_Mask), "bGPDlayer_Mask");
1439  BLI_addtail(&gpl->mask_layers, mask);
1440  BLI_strncpy(mask->name, name, sizeof(mask->name));
1441  gpl->act_mask++;
1442 
1443  return mask;
1444 }
1445 
1447 {
1448  BLI_freelinkN(&gpl->mask_layers, mask);
1449  gpl->act_mask--;
1450  CLAMP_MIN(gpl->act_mask, 0);
1451 }
1452 
1453 void BKE_gpencil_layer_mask_remove_ref(bGPdata *gpd, const char *name)
1454 {
1455  bGPDlayer_Mask *mask_next;
1456 
1457  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
1458  for (bGPDlayer_Mask *mask = gpl->mask_layers.first; mask; mask = mask_next) {
1459  mask_next = mask->next;
1460  if (STREQ(mask->name, name)) {
1462  }
1463  }
1464  }
1465 }
1466 
1467 static int gpencil_cb_sort_masks(const void *arg1, const void *arg2)
1468 {
1469  /* sort is inverted as layer list. */
1470  const struct bGPDlayer_Mask *mask1 = arg1;
1471  const struct bGPDlayer_Mask *mask2 = arg2;
1472  int val = 0;
1473 
1474  if (mask1->sort_index < mask2->sort_index) {
1475  val = 1;
1476  }
1477  else if (mask1->sort_index > mask2->sort_index) {
1478  val = -1;
1479  }
1480 
1481  return val;
1482 }
1483 
1485 {
1486  /* Update sort index. */
1488  bGPDlayer *gpl_mask = BKE_gpencil_layer_named_get(gpd, mask->name);
1489  if (gpl_mask != NULL) {
1490  mask->sort_index = BLI_findindex(&gpd->layers, gpl_mask);
1491  }
1492  else {
1493  mask->sort_index = 0;
1494  }
1495  }
1497 }
1498 
1500 {
1501  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
1502  BKE_gpencil_layer_mask_sort(gpd, gpl);
1503  }
1504 }
1505 
1506 void BKE_gpencil_layer_mask_copy(const bGPDlayer *gpl_src, bGPDlayer *gpl_dst)
1507 {
1508  BLI_listbase_clear(&gpl_dst->mask_layers);
1509  LISTBASE_FOREACH (bGPDlayer_Mask *, mask_src, &gpl_src->mask_layers) {
1510  bGPDlayer_Mask *mask_dst = MEM_dupallocN(mask_src);
1511  mask_dst->prev = mask_dst->next = NULL;
1512  BLI_addtail(&gpl_dst->mask_layers, mask_dst);
1513  }
1514 }
1515 
1517 {
1519  if (BKE_gpencil_layer_named_get(gpd, mask->name) == NULL) {
1521  }
1522  }
1523 }
1524 
1526 {
1527  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
1529  }
1530 }
1531 
1532 static int gpencil_cb_cmp_frame(void *thunk, const void *a, const void *b)
1533 {
1534  const bGPDframe *frame_a = a;
1535  const bGPDframe *frame_b = b;
1536 
1537  if (frame_a->framenum < frame_b->framenum) {
1538  return -1;
1539  }
1540  if (frame_a->framenum > frame_b->framenum) {
1541  return 1;
1542  }
1543  if (thunk != NULL) {
1544  *((bool *)thunk) = true;
1545  }
1546  /* Sort selected last. */
1547  if ((frame_a->flag & GP_FRAME_SELECT) && ((frame_b->flag & GP_FRAME_SELECT) == 0)) {
1548  return 1;
1549  }
1550  return 0;
1551 }
1552 
1553 void BKE_gpencil_layer_frames_sort(struct bGPDlayer *gpl, bool *r_has_duplicate_frames)
1554 {
1555  BLI_listbase_sort_r(&gpl->frames, gpencil_cb_cmp_frame, r_has_duplicate_frames);
1556 }
1557 
1559 {
1560  /* error checking */
1561  if (ELEM(NULL, gpd, gpd->layers.first)) {
1562  return NULL;
1563  }
1564 
1565  /* loop over layers until found (assume only one active) */
1566  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
1567  if (gpl->flag & GP_LAYER_ACTIVE) {
1568  return gpl;
1569  }
1570  }
1571 
1572  /* no active layer found */
1573  return NULL;
1574 }
1575 
1576 bGPDlayer *BKE_gpencil_layer_get_by_name(bGPdata *gpd, char *name, int first_if_not_found)
1577 {
1578  bGPDlayer *gpl;
1579  int i = 0;
1580 
1581  /* error checking */
1582  if (ELEM(NULL, gpd, gpd->layers.first)) {
1583  return NULL;
1584  }
1585 
1586  /* loop over layers until found (assume only one active) */
1587  for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
1588  if (STREQ(name, gpl->info)) {
1589  return gpl;
1590  }
1591  i++;
1592  }
1593 
1594  /* no such layer */
1595  if (first_if_not_found) {
1596  return gpd->layers.first;
1597  }
1598  return NULL;
1599 }
1600 
1602 {
1603  /* error checking */
1604  if (ELEM(NULL, gpd, gpd->layers.first, active)) {
1605  return;
1606  }
1607 
1608  /* loop over layers deactivating all */
1609  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
1610  gpl->flag &= ~GP_LAYER_ACTIVE;
1611  if (gpd->flag & GP_DATA_AUTOLOCK_LAYERS) {
1612  gpl->flag |= GP_LAYER_LOCKED;
1613  }
1614  }
1615 
1616  /* set as active one */
1617  active->flag |= GP_LAYER_ACTIVE;
1618  if (gpd->flag & GP_DATA_AUTOLOCK_LAYERS) {
1619  active->flag &= ~GP_LAYER_LOCKED;
1620  }
1621 }
1622 
1623 void BKE_gpencil_layer_autolock_set(bGPdata *gpd, const bool unlock)
1624 {
1625  BLI_assert(gpd != NULL);
1626 
1627  if (gpd->flag & GP_DATA_AUTOLOCK_LAYERS) {
1628  bGPDlayer *layer_active = BKE_gpencil_layer_active_get(gpd);
1629 
1630  /* Lock all other layers */
1631  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
1632  /* unlock active layer */
1633  if (gpl == layer_active) {
1634  gpl->flag &= ~GP_LAYER_LOCKED;
1635  }
1636  else {
1637  gpl->flag |= GP_LAYER_LOCKED;
1638  }
1639  }
1640  }
1641  else {
1642  /* If disable is better unlock all layers by default or it looks there is
1643  * a problem in the UI because the user expects all layers will be unlocked
1644  */
1645  if (unlock) {
1646  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
1647  gpl->flag &= ~GP_LAYER_LOCKED;
1648  }
1649  }
1650  }
1651 }
1652 
1654 {
1655  /* error checking */
1656  if (ELEM(NULL, gpd, gpl)) {
1657  return;
1658  }
1659 
1660  /* free layer */
1662 
1663  /* Free Masks. */
1665 
1666  /* Remove any reference to that layer in masking lists. */
1668 
1669  /* free icon providing preview of icon color */
1671 
1672  BLI_freelinkN(&gpd->layers, gpl);
1673 }
1674 
1676 {
1677  Material *ma = NULL;
1678 
1679  if ((brush != NULL) && (brush->gpencil_settings != NULL) &&
1680  (brush->gpencil_settings->material != NULL)) {
1681  ma = brush->gpencil_settings->material;
1682  }
1683 
1684  return ma;
1685 }
1686 
1688 {
1689  BLI_assert(brush);
1690  BLI_assert(brush->gpencil_settings);
1691  if (brush->gpencil_settings->material != ma) {
1692  if (brush->gpencil_settings->material) {
1694  }
1695  if (ma) {
1696  id_us_plus(&ma->id);
1697  }
1698  brush->gpencil_settings->material = ma;
1699  }
1700 }
1701 
1703 {
1706 
1707  /* check if the material is already on object material slots and add it if missing */
1708  if (ma && BKE_gpencil_object_material_index_get(ob, ma) < 0) {
1709  BKE_object_material_slot_add(bmain, ob);
1711  }
1712 
1713  return ma;
1714  }
1715 
1716  /* using active material instead */
1717  return BKE_object_material_get(ob, ob->actcol);
1718 }
1719 
1721 {
1722  if (!material) {
1723  return -1;
1724  }
1726  if (index < 0) {
1727  BKE_object_material_slot_add(bmain, ob);
1729  return ob->totcol - 1;
1730  }
1731  return index;
1732 }
1733 
1734 Material *BKE_gpencil_object_material_new(Main *bmain, Object *ob, const char *name, int *r_index)
1735 {
1736  Material *ma = BKE_gpencil_material_add(bmain, name);
1737  id_us_min(&ma->id); /* no users yet */
1738 
1739  BKE_object_material_slot_add(bmain, ob);
1741 
1742  if (r_index) {
1743  *r_index = ob->actcol - 1;
1744  }
1745  return ma;
1746 }
1747 
1749 {
1750  if ((brush) && (brush->gpencil_settings) &&
1753  return ma;
1754  }
1755 
1756  return BKE_object_material_get(ob, ob->actcol);
1757 }
1758 
1760 {
1761  if ((brush) && (brush->gpencil_settings->flag & GP_BRUSH_MATERIAL_PINNED)) {
1763  }
1764 
1765  return ob->actcol - 1;
1766 }
1767 
1769  Object *ob,
1770  ToolSettings *ts)
1771 {
1772  if (ts && ts->gp_paint && ts->gp_paint->paint.brush) {
1774  bmain, ob, ts->gp_paint->paint.brush);
1775  }
1776 
1778 }
1779 
1781  Object *ob,
1782  Brush *brush)
1783 {
1784  if (brush) {
1786  if (ma) {
1787  return ma;
1788  }
1790  /* it is easier to just unpin a NULL material, instead of setting a new one */
1792  }
1793  }
1795 }
1796 
1798 {
1799  Material *ma = BKE_object_material_get(ob, ob->actcol);
1800  if (ma) {
1801  return ma;
1802  }
1803 
1805 }
1806 
1808 {
1809  Material *ma = NULL;
1810 
1811  /* sanity checks */
1812  if (ob == NULL) {
1813  return NULL;
1814  }
1815 
1817  if (ma->gp_style == NULL) {
1819  }
1820 
1821  return ma;
1822 }
1823 
1824 /* ************************************************** */
1826 {
1827  const bGPDspoint *pt;
1828  int i;
1829  for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
1830  if (pt->flag & GP_SPOINT_SELECT) {
1831  return true;
1832  }
1833  }
1834  return false;
1835 }
1836 
1837 /* ************************************************** */
1838 /* GP Object - Vertex Groups */
1839 
1841 {
1842  bGPdata *gpd = ob->data;
1843  MDeformVert *dvert = NULL;
1844 
1845  const int def_nr = BLI_findindex(&gpd->vertex_group_names, defgroup);
1846  const int totgrp = BLI_listbase_count(&gpd->vertex_group_names);
1847 
1848  /* Remove points data */
1849  if (gpd) {
1850  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
1851  LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
1852  LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
1853  if (gps->dvert != NULL) {
1854  for (int i = 0; i < gps->totpoints; i++) {
1855  dvert = &gps->dvert[i];
1856  MDeformWeight *dw = BKE_defvert_find_index(dvert, def_nr);
1857  if (dw != NULL) {
1858  BKE_defvert_remove_group(dvert, dw);
1859  }
1860  /* Reorganize weights for other groups after deleted one. */
1861  for (int g = 0; g < totgrp; g++) {
1862  dw = BKE_defvert_find_index(dvert, g);
1863  if ((dw != NULL) && (dw->def_nr > def_nr)) {
1864  dw->def_nr--;
1865  }
1866  }
1867  }
1868  }
1869  }
1870  }
1871  }
1872  }
1873 
1874  /* Remove the group */
1875  BLI_freelinkN(&gpd->vertex_group_names, defgroup);
1876 
1877  /* Update the active deform index if necessary. */
1878  const int active_index = BKE_object_defgroup_active_index_get(ob);
1879  if (active_index > def_nr) {
1880  BKE_object_defgroup_active_index_set(ob, active_index - 1);
1881  }
1882  /* Keep a valid active index if we still have some vertex groups. */
1886  }
1887 
1889 }
1890 
1892 {
1893  if (gps->dvert == NULL) {
1894  gps->dvert = MEM_callocN(sizeof(MDeformVert) * gps->totpoints, "gp_stroke_weights");
1895  }
1896 }
1897 
1898 /* ************************************************** */
1899 
1900 void BKE_gpencil_frame_range_selected(bGPDlayer *gpl, int *r_initframe, int *r_endframe)
1901 {
1902  *r_initframe = gpl->actframe->framenum;
1903  *r_endframe = gpl->actframe->framenum;
1904 
1905  LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
1906  if (gpf->flag & GP_FRAME_SELECT) {
1907  if (gpf->framenum < *r_initframe) {
1908  *r_initframe = gpf->framenum;
1909  }
1910  if (gpf->framenum > *r_endframe) {
1911  *r_endframe = gpf->framenum;
1912  }
1913  }
1914  }
1915 }
1916 
1918  bGPDframe *gpf, int actnum, int f_init, int f_end, CurveMapping *cur_falloff)
1919 {
1920  float fnum = 0.5f; /* default mid curve */
1921  float value;
1922 
1923  /* check curve is available */
1924  if (cur_falloff == NULL) {
1925  return 1.0f;
1926  }
1927 
1928  /* frames to the right of the active frame */
1929  if (gpf->framenum < actnum) {
1930  fnum = (float)(gpf->framenum - f_init) / (actnum - f_init);
1931  fnum *= 0.5f;
1932  value = BKE_curvemapping_evaluateF(cur_falloff, 0, fnum);
1933  }
1934  /* frames to the left of the active frame */
1935  else if (gpf->framenum > actnum) {
1936  fnum = (float)(gpf->framenum - actnum) / (f_end - actnum);
1937  fnum *= 0.5f;
1938  value = BKE_curvemapping_evaluateF(cur_falloff, 0, fnum + 0.5f);
1939  }
1940  else {
1941  /* Center of the curve. */
1942  value = BKE_curvemapping_evaluateF(cur_falloff, 0, 0.5f);
1943  }
1944 
1945  return value;
1946 }
1947 
1948 void BKE_gpencil_material_index_reassign(bGPdata *gpd, int totcol, int index)
1949 {
1950  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
1951  LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
1952  LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
1953  /* reassign strokes */
1954  if ((gps->mat_nr > index) || (gps->mat_nr > totcol - 1)) {
1955  gps->mat_nr--;
1956  CLAMP_MIN(gps->mat_nr, 0);
1957  }
1958  }
1959  }
1960  }
1961 }
1962 
1964 {
1965  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
1966  LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
1967  LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
1968  if (gps->mat_nr == index) {
1969  return true;
1970  }
1971  }
1972  }
1973  }
1974 
1975  return false;
1976 }
1977 
1979  const unsigned int *remap,
1980  unsigned int remap_len)
1981 {
1982  const short remap_len_short = (short)remap_len;
1983 
1984 #define MAT_NR_REMAP(n) \
1985  if (n < remap_len_short) { \
1986  BLI_assert(n >= 0 && remap[n] < remap_len_short); \
1987  n = remap[n]; \
1988  } \
1989  ((void)0)
1990 
1991  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
1992  LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
1993  LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
1994  /* reassign strokes */
1995  MAT_NR_REMAP(gps->mat_nr);
1996  }
1997  }
1998  }
1999 
2000 #undef MAT_NR_REMAP
2001 }
2002 
2004  const float hue_threshold,
2005  const float sat_threshold,
2006  const float val_threshold,
2007  GHash *r_mat_table)
2008 {
2009  bool changed = false;
2010 
2011  Material *ma_primary = NULL;
2012  Material *ma_secondary = NULL;
2013  MaterialGPencilStyle *gp_style_primary = NULL;
2014  MaterialGPencilStyle *gp_style_secondary = NULL;
2015  GHash *mat_used = BLI_ghash_int_new(__func__);
2016 
2017  short *totcol = BKE_object_material_len_p(ob);
2018  if (totcol == 0) {
2019  return changed;
2020  }
2021 
2022  for (int idx_primary = 0; idx_primary < *totcol; idx_primary++) {
2023  /* Read primary material to compare. */
2024  ma_primary = BKE_gpencil_material(ob, idx_primary + 1);
2025  if (ma_primary == NULL) {
2026  continue;
2027  }
2028  for (int idx_secondary = 0; idx_secondary < *totcol; idx_secondary++) {
2029  if ((idx_secondary == idx_primary) ||
2030  BLI_ghash_haskey(r_mat_table, POINTER_FROM_INT(idx_secondary))) {
2031  continue;
2032  }
2033  if (BLI_ghash_haskey(mat_used, POINTER_FROM_INT(idx_secondary))) {
2034  continue;
2035  }
2036 
2037  /* Read secondary material to compare with primary material. */
2038  ma_secondary = BKE_gpencil_material(ob, idx_secondary + 1);
2039  if ((ma_secondary == NULL) ||
2040  (BLI_ghash_haskey(r_mat_table, POINTER_FROM_INT(idx_secondary)))) {
2041  continue;
2042  }
2043  gp_style_primary = ma_primary->gp_style;
2044  gp_style_secondary = ma_secondary->gp_style;
2045 
2046  if ((gp_style_primary == NULL) || (gp_style_secondary == NULL) ||
2047  (gp_style_secondary->flag & GP_MATERIAL_LOCKED)) {
2048  continue;
2049  }
2050 
2051  /* Check materials have the same mode. */
2052  if (gp_style_primary->mode != gp_style_secondary->mode) {
2053  continue;
2054  }
2055 
2056  /* Check materials have same stroke and fill attributes. */
2057  if ((gp_style_primary->flag & GP_MATERIAL_STROKE_SHOW) !=
2058  (gp_style_secondary->flag & GP_MATERIAL_STROKE_SHOW)) {
2059  continue;
2060  }
2061 
2062  if ((gp_style_primary->flag & GP_MATERIAL_FILL_SHOW) !=
2063  (gp_style_secondary->flag & GP_MATERIAL_FILL_SHOW)) {
2064  continue;
2065  }
2066 
2067  /* Check materials have the same type. */
2068  if ((gp_style_primary->stroke_style != gp_style_secondary->stroke_style) ||
2069  (gp_style_primary->fill_style != gp_style_secondary->fill_style)) {
2070  continue;
2071  }
2072 
2073  float s_hsv_a[3], s_hsv_b[3], f_hsv_a[3], f_hsv_b[3], col[3];
2074  zero_v3(s_hsv_a);
2075  zero_v3(s_hsv_b);
2076  zero_v3(f_hsv_a);
2077  zero_v3(f_hsv_b);
2078 
2079  copy_v3_v3(col, gp_style_primary->stroke_rgba);
2080  rgb_to_hsv_compat_v(col, s_hsv_a);
2081  copy_v3_v3(col, gp_style_secondary->stroke_rgba);
2082  rgb_to_hsv_compat_v(col, s_hsv_b);
2083 
2084  copy_v3_v3(col, gp_style_primary->fill_rgba);
2085  rgb_to_hsv_compat_v(col, f_hsv_a);
2086  copy_v3_v3(col, gp_style_secondary->fill_rgba);
2087  rgb_to_hsv_compat_v(col, f_hsv_b);
2088 
2089  /* Check stroke and fill color. */
2090  if ((!compare_ff(s_hsv_a[0], s_hsv_b[0], hue_threshold)) ||
2091  (!compare_ff(s_hsv_a[1], s_hsv_b[1], sat_threshold)) ||
2092  (!compare_ff(s_hsv_a[2], s_hsv_b[2], val_threshold)) ||
2093  (!compare_ff(f_hsv_a[0], f_hsv_b[0], hue_threshold)) ||
2094  (!compare_ff(f_hsv_a[1], f_hsv_b[1], sat_threshold)) ||
2095  (!compare_ff(f_hsv_a[2], f_hsv_b[2], val_threshold)) ||
2096  (!compare_ff(gp_style_primary->stroke_rgba[3],
2097  gp_style_secondary->stroke_rgba[3],
2098  val_threshold)) ||
2099  (!compare_ff(
2100  gp_style_primary->fill_rgba[3], gp_style_secondary->fill_rgba[3], val_threshold))) {
2101  continue;
2102  }
2103 
2104  /* Save conversion indexes. */
2105  if (!BLI_ghash_haskey(r_mat_table, POINTER_FROM_INT(idx_secondary))) {
2107  r_mat_table, POINTER_FROM_INT(idx_secondary), POINTER_FROM_INT(idx_primary));
2108  changed = true;
2109 
2110  if (!BLI_ghash_haskey(mat_used, POINTER_FROM_INT(idx_primary))) {
2111  BLI_ghash_insert(mat_used, POINTER_FROM_INT(idx_primary), POINTER_FROM_INT(idx_primary));
2112  }
2113  }
2114  }
2115  }
2116  /* Free hash memory. */
2117  BLI_ghash_free(mat_used, NULL, NULL);
2118 
2119  return changed;
2120 }
2121 
2123  const float hue_threshold,
2124  const float sat_threshold,
2125  const float val_threshold,
2126  int *r_removed)
2127 {
2128  bGPdata *gpd = ob->data;
2129 
2130  short *totcol = BKE_object_material_len_p(ob);
2131  if (totcol == 0) {
2132  *r_removed = 0;
2133  return 0;
2134  }
2135 
2136  /* Review materials. */
2137  GHash *mat_table = BLI_ghash_int_new(__func__);
2138 
2140  ob, hue_threshold, sat_threshold, val_threshold, mat_table);
2141 
2142  *r_removed = BLI_ghash_len(mat_table);
2143 
2144  /* Update stroke material index. */
2145  if (changed) {
2146  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
2147  if (gpl->flag & GP_LAYER_HIDE) {
2148  continue;
2149  }
2150 
2151  LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
2152  LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
2153  /* Check if the color is editable. */
2154  MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
2155  if (gp_style != NULL) {
2156  if (gp_style->flag & GP_MATERIAL_HIDE) {
2157  continue;
2158  }
2159  if (((gpl->flag & GP_LAYER_UNLOCK_COLOR) == 0) &&
2160  (gp_style->flag & GP_MATERIAL_LOCKED)) {
2161  continue;
2162  }
2163  }
2164 
2165  if (BLI_ghash_haskey(mat_table, POINTER_FROM_INT(gps->mat_nr))) {
2166  int *idx = BLI_ghash_lookup(mat_table, POINTER_FROM_INT(gps->mat_nr));
2167  gps->mat_nr = POINTER_AS_INT(idx);
2168  }
2169  }
2170  }
2171  }
2172  }
2173 
2174  /* Free hash memory. */
2175  BLI_ghash_free(mat_table, NULL, NULL);
2176 
2177  return changed;
2178 }
2179 
2181 {
2182  gpd->totlayer = 0;
2183  gpd->totframe = 0;
2184  gpd->totstroke = 0;
2185  gpd->totpoint = 0;
2186 
2187  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
2188  gpd->totlayer++;
2189  LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
2190  gpd->totframe++;
2191  LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
2192  gpd->totstroke++;
2193  gpd->totpoint += gps->totpoints;
2194  }
2195  }
2196  }
2197 }
2198 
2200 {
2201  short *totcol = BKE_object_material_len_p(ob);
2202  Material *read_ma = NULL;
2203  for (short i = 0; i < *totcol; i++) {
2204  read_ma = BKE_object_material_get(ob, i + 1);
2205  if (ma == read_ma) {
2206  return i;
2207  }
2208  }
2209 
2210  return -1;
2211 }
2212 
2214 {
2215  short *totcol = BKE_object_material_len_p(ob);
2216  Material *read_ma = NULL;
2217  for (short i = 0; i < *totcol; i++) {
2218  read_ma = BKE_object_material_get(ob, i + 1);
2219  /* Material names are like "MAMaterial.001" */
2220  if (STREQ(name, &read_ma->id.name[2])) {
2221  return i;
2222  }
2223  }
2224 
2225  return -1;
2226 }
2227 
2229  Object *ob,
2230  const char *name,
2231  int *r_index)
2232 {
2234  if (index != -1) {
2235  *r_index = index;
2236  return BKE_object_material_get(ob, index + 1);
2237  }
2238  return BKE_gpencil_object_material_new(bmain, ob, name, r_index);
2239 }
2240 
2242 {
2243  const char *hexcol[] = {
2244  "FFFFFF", "F2F2F2", "E6E6E6", "D9D9D9", "CCCCCC", "BFBFBF", "B2B2B2", "A6A6A6", "999999",
2245  "8C8C8C", "808080", "737373", "666666", "595959", "4C4C4C", "404040", "333333", "262626",
2246  "1A1A1A", "000000", "F2FC24", "FFEA00", "FEA711", "FE8B68", "FB3B02", "FE3521", "D00000",
2247  "A81F3D", "780422", "2B0000", "F1E2C5", "FEE4B3", "FEDABB", "FEC28E", "D88F57", "BD6340",
2248  "A2402B", "63352D", "6B2833", "34120C", "E7CB8F", "D1B38B", "C1B17F", "D7980B", "FFB100",
2249  "FE8B00", "FF6A00", "B74100", "5F3E1D", "3B2300", "FECADA", "FE65CB", "FE1392", "DD3062",
2250  "C04A6D", "891688", "4D2689", "441521", "2C1139", "241422", "FFFF7D", "FFFF00", "FF7F00",
2251  "FF7D7D", "FF7DFF", "FF00FE", "FF007F", "FF0000", "7F0000", "0A0A00", "F6FDFF", "E9F7FF",
2252  "CFE6FE", "AAC7FE", "77B3FE", "1E74FD", "0046AA", "2F4476", "003052", "0E0E25", "EEF5F0",
2253  "D6E5DE", "ACD8B9", "6CADC6", "42A9AF", "007F7F", "49675C", "2E4E4E", "1D3239", "0F1C21",
2254  "D8FFF4", "B8F4F5", "AECCB5", "76C578", "358757", "409B68", "468768", "1F512B", "2A3C37",
2255  "122E1D", "EFFFC9", "E6F385", "BCF51C", "D4DC18", "82D322", "5C7F00", "59932B", "297F00",
2256  "004320", "1C3322", "00FF7F", "00FF00", "7DFF7D", "7DFFFF", "00FFFF", "7D7DFF", "7F00FF",
2257  "0000FF", "3F007F", "00007F"};
2258 
2260  if (ts->gp_paint->paint.palette != NULL) {
2261  return;
2262  }
2263 
2264  /* Try to find the default palette. */
2265  const char *palette_id = "Palette";
2266  struct Palette *palette = BLI_findstring(&bmain->palettes, palette_id, offsetof(ID, name) + 2);
2267 
2268  if (palette == NULL) {
2269  /* Fall back to the first palette. */
2270  palette = bmain->palettes.first;
2271  }
2272 
2273  if (palette == NULL) {
2274  /* Fall back to creating a palette. */
2275  palette = BKE_palette_add(bmain, palette_id);
2276  id_us_min(&palette->id);
2277 
2278  /* Create Colors. */
2279  for (int i = 0; i < ARRAY_SIZE(hexcol); i++) {
2280  PaletteColor *palcol = BKE_palette_color_add(palette);
2281  hex_to_rgb(hexcol[i], palcol->rgb, palcol->rgb + 1, palcol->rgb + 2);
2282  }
2283  }
2284 
2285  BLI_assert(palette != NULL);
2286  BKE_paint_palette_set(&ts->gp_paint->paint, palette);
2287  BKE_paint_palette_set(&ts->gp_vertexpaint->paint, palette);
2288 }
2289 
2291  SpaceImage *sima, bGPdata *gpd, bGPDframe *gpf, const float size, const bool mask)
2292 {
2293  Image *image = sima->image;
2294  bool done = false;
2295 
2296  if (image == NULL) {
2297  return false;
2298  }
2299 
2300  ImageUser iuser = sima->iuser;
2301  void *lock;
2302  ImBuf *ibuf;
2303 
2304  ibuf = BKE_image_acquire_ibuf(image, &iuser, &lock);
2305 
2306  if (ibuf && ibuf->rect) {
2307  int img_x = ibuf->x;
2308  int img_y = ibuf->y;
2309 
2310  float color[4];
2311  bGPDspoint *pt;
2312  for (int row = 0; row < img_y; row++) {
2313  /* Create new stroke */
2314  bGPDstroke *gps = BKE_gpencil_stroke_add(gpf, 0, img_x, size * 1000, false);
2315  done = true;
2316  for (int col = 0; col < img_x; col++) {
2317  IMB_sampleImageAtLocation(ibuf, col, row, true, color);
2318  pt = &gps->points[col];
2319  pt->pressure = 1.0f;
2320  pt->x = col * size;
2321  pt->z = row * size;
2322  if (!mask) {
2323  copy_v3_v3(pt->vert_color, color);
2324  pt->vert_color[3] = 1.0f;
2325  pt->strength = color[3];
2326  }
2327  else {
2328  zero_v3(pt->vert_color);
2329  pt->vert_color[3] = 1.0f;
2330  pt->strength = 1.0f - color[3];
2331  }
2332 
2333  /* Selet Alpha points. */
2334  if (pt->strength < 0.03f) {
2335  gps->flag |= GP_STROKE_SELECT;
2336  pt->flag |= GP_SPOINT_SELECT;
2337  }
2338  }
2339 
2340  if (gps->flag & GP_STROKE_SELECT) {
2342  }
2343 
2345  }
2346  }
2347 
2348  /* Free memory. */
2350 
2351  return done;
2352 }
2353 
2361 static bool gpencil_is_layer_mask(ViewLayer *view_layer, bGPdata *gpd, bGPDlayer *gpl_mask)
2362 {
2363  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
2364  if ((gpl->viewlayername[0] != '\0') && (!STREQ(view_layer->name, gpl->viewlayername))) {
2365  continue;
2366  }
2367 
2368  /* Skip if masks are disabled for this view layer. */
2369  if (gpl->flag & GP_LAYER_DISABLE_MASKS_IN_VIEWLAYER) {
2370  continue;
2371  }
2372 
2373  LISTBASE_FOREACH (bGPDlayer_Mask *, mask, &gpl->mask_layers) {
2374  if (STREQ(gpl_mask->info, mask->name)) {
2375  return true;
2376  }
2377  }
2378  }
2379 
2380  return false;
2381 }
2382 
2383 /* -------------------------------------------------------------------- */
2390  gpIterCb layer_cb,
2391  gpIterCb stroke_cb,
2392  void *thunk)
2393 {
2394  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
2395 
2396  if (gpl->flag & GP_LAYER_HIDE) {
2397  continue;
2398  }
2399 
2400  /* If scale to 0 the layer must be invisible. */
2401  if (is_zero_v3(gpl->scale)) {
2402  continue;
2403  }
2404 
2405  bGPDframe *act_gpf = gpl->actframe;
2406  if (layer_cb) {
2407  layer_cb(gpl, act_gpf, NULL, thunk);
2408  }
2409 
2410  if (act_gpf) {
2411  LISTBASE_FOREACH (bGPDstroke *, gps, &act_gpf->strokes) {
2412  if (gps->totpoints == 0) {
2413  continue;
2414  }
2415  stroke_cb(gpl, act_gpf, gps, thunk);
2416  }
2417  }
2418  }
2419 }
2420 
2423 /* -------------------------------------------------------------------- */
2431  Object *ob,
2432  gpIterCb layer_cb,
2433  gpIterCb stroke_cb,
2434  void *thunk,
2435  bool do_onion,
2436  int cfra)
2437 {
2438  bGPdata *gpd = (bGPdata *)ob->data;
2439  const bool is_multiedit = (GPENCIL_MULTIEDIT_SESSIONS_ON(gpd) && (!GPENCIL_PLAY_ON(gpd)));
2440  const bool is_onion = do_onion && ((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0);
2441  const bool is_drawing = (gpd->runtime.sbuffer_used > 0);
2442 
2443  /* Onion skinning. */
2444  const bool onion_mode_abs = (gpd->onion_mode == GP_ONION_MODE_ABSOLUTE);
2445  const bool onion_mode_sel = (gpd->onion_mode == GP_ONION_MODE_SELECTED);
2446  const bool onion_loop = (gpd->onion_flag & GP_ONION_LOOP) != 0;
2447  const short onion_keytype = gpd->onion_keytype;
2448 
2449  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
2450  /* Reset by layer. */
2451  bool is_before_first = false;
2452 
2453  bGPDframe *act_gpf = gpl->actframe;
2454  bGPDframe *sta_gpf = act_gpf;
2455  bGPDframe *end_gpf = act_gpf ? act_gpf->next : NULL;
2456  float prev_opacity = gpl->opacity;
2457 
2458  if (gpl->flag & GP_LAYER_HIDE) {
2459  continue;
2460  }
2461 
2462  /* If scale to 0 the layer must be invisible. */
2463  if (is_zero_v3(gpl->scale)) {
2464  continue;
2465  }
2466 
2467  /* Hide the layer if it's defined a view layer filter. This is used to
2468  * generate renders, putting only selected GP layers for each View Layer.
2469  * This is used only in final render and never in Viewport. */
2470  if ((view_layer != NULL) && (gpl->viewlayername[0] != '\0') &&
2471  (!STREQ(view_layer->name, gpl->viewlayername))) {
2472  /* Do not skip masks when rendering the view-layer so that it can still be used to clip
2473  * other layers. Instead set their opacity to zero. */
2474  if (gpencil_is_layer_mask(view_layer, gpd, gpl)) {
2475  gpl->opacity = 0.0f;
2476  }
2477  else {
2478  continue;
2479  }
2480  }
2481 
2482  if (is_multiedit) {
2483  sta_gpf = end_gpf = NULL;
2484  /* Check the whole range and tag the editable frames. */
2485  LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
2486  if (act_gpf != NULL && (gpf == act_gpf || (gpf->flag & GP_FRAME_SELECT))) {
2487  gpf->runtime.onion_id = 0;
2488  if (do_onion) {
2489  if (gpf->framenum < act_gpf->framenum) {
2490  gpf->runtime.onion_id = -1;
2491  }
2492  else {
2493  gpf->runtime.onion_id = 1;
2494  }
2495  }
2496 
2497  if (sta_gpf == NULL) {
2498  sta_gpf = gpf;
2499  }
2500  end_gpf = gpf->next;
2501  }
2502  else {
2503  gpf->runtime.onion_id = INT_MAX;
2504  }
2505  }
2506  }
2507  else if (is_onion && (gpl->onion_flag & GP_LAYER_ONIONSKIN)) {
2508  /* Special cases when cframe is before first frame. */
2509  bGPDframe *gpf_first = gpl->frames.first;
2510  if ((gpf_first != NULL) && (act_gpf != NULL) && (gpf_first->framenum > act_gpf->framenum)) {
2511  is_before_first = true;
2512  }
2513  if ((gpf_first != NULL) && (act_gpf == NULL)) {
2514  act_gpf = gpf_first;
2515  is_before_first = true;
2516  }
2517 
2518  if (act_gpf) {
2519  bGPDframe *last_gpf = gpl->frames.last;
2520 
2521  int frame_len = 0;
2522  LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
2523  gpf->runtime.frameid = frame_len++;
2524  }
2525 
2526  LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
2527  bool is_wrong_keytype = (onion_keytype > -1) && (gpf->key_type != onion_keytype);
2528  bool is_in_range;
2529  int delta = (onion_mode_abs) ? (gpf->framenum - cfra) :
2530  (gpf->runtime.frameid - act_gpf->runtime.frameid);
2531 
2532  if (is_before_first) {
2533  delta++;
2534  }
2535 
2536  if (onion_mode_sel) {
2537  is_in_range = (gpf->flag & GP_FRAME_SELECT) != 0;
2538  }
2539  else {
2540  is_in_range = (-delta <= gpd->gstep) && (delta <= gpd->gstep_next);
2541 
2542  if (onion_loop && !is_in_range) {
2543  /* We wrap the value using the last frame and 0 as reference. */
2544  /* FIXME: This might not be good for animations not starting at 0. */
2545  int shift = (onion_mode_abs) ? last_gpf->framenum : last_gpf->runtime.frameid;
2546  delta += (delta < 0) ? (shift + 1) : -(shift + 1);
2547  /* Test again with wrapped value. */
2548  is_in_range = (-delta <= gpd->gstep) && (delta <= gpd->gstep_next);
2549  }
2550  }
2551  /* Mask frames that have wrong keytype of are not in range. */
2552  gpf->runtime.onion_id = (is_wrong_keytype || !is_in_range) ? INT_MAX : delta;
2553  }
2554  /* Active frame is always shown. */
2555  if (!is_before_first || is_drawing) {
2556  act_gpf->runtime.onion_id = 0;
2557  }
2558  }
2559 
2560  sta_gpf = gpl->frames.first;
2561  end_gpf = NULL;
2562  }
2563  else {
2564  /* Bypass multiedit/onion skinning. */
2565  end_gpf = sta_gpf = NULL;
2566  }
2567 
2568  if (sta_gpf == NULL && act_gpf == NULL) {
2569  if (layer_cb) {
2570  layer_cb(gpl, act_gpf, NULL, thunk);
2571  }
2572  gpl->opacity = prev_opacity;
2573  continue;
2574  }
2575 
2576  /* Draw multiedit/onion skinning first */
2577  for (bGPDframe *gpf = sta_gpf; gpf && gpf != end_gpf; gpf = gpf->next) {
2578  if ((gpf->runtime.onion_id == INT_MAX || gpf == act_gpf) && (!is_before_first)) {
2579  continue;
2580  }
2581 
2582  /* Only do once for frame before first. */
2583  if (is_before_first && gpf == act_gpf) {
2584  is_before_first = false;
2585  }
2586 
2587  if (layer_cb) {
2588  layer_cb(gpl, gpf, NULL, thunk);
2589  }
2590 
2591  if (stroke_cb) {
2592  LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
2593  if (gps->totpoints == 0) {
2594  continue;
2595  }
2596  stroke_cb(gpl, gpf, gps, thunk);
2597  }
2598  }
2599  }
2600  /* Draw Active frame on top. */
2601  /* Use evaluated frame (with modifiers for active stroke)/ */
2602  act_gpf = gpl->actframe;
2603  if (act_gpf) {
2604  act_gpf->runtime.onion_id = 0;
2605  if (layer_cb) {
2606  layer_cb(gpl, act_gpf, NULL, thunk);
2607  }
2608 
2609  /* If layer solo mode and Paint mode, only keyframes with data are displayed. */
2610  if (GPENCIL_PAINT_MODE(gpd) && (gpl->flag & GP_LAYER_SOLO_MODE) &&
2611  (act_gpf->framenum != cfra)) {
2612  gpl->opacity = prev_opacity;
2613  continue;
2614  }
2615  if (stroke_cb) {
2616  LISTBASE_FOREACH (bGPDstroke *, gps, &act_gpf->strokes) {
2617  if (gps->totpoints == 0) {
2618  continue;
2619  }
2620  stroke_cb(gpl, act_gpf, gps, thunk);
2621  }
2622  }
2623  }
2624 
2625  /* Restore the opacity in case it was overwritten (used to hide masks in render). */
2626  gpl->opacity = prev_opacity;
2627  }
2628 }
2629 
2631  const struct bGPDframe *gpf_eval)
2632 {
2633  bGPDstroke *gps_eval = gpf_eval->strokes.first;
2634  LISTBASE_FOREACH (bGPDstroke *, gps_orig, &gpf_orig->strokes) {
2635 
2636  /* Assign original stroke pointer. */
2637  if (gps_eval != NULL) {
2638  gps_eval->runtime.gps_orig = gps_orig;
2639 
2640  /* Assign original point pointer. */
2641  for (int i = 0; i < gps_orig->totpoints; i++) {
2642  if (i > gps_eval->totpoints - 1) {
2643  break;
2644  }
2645  bGPDspoint *pt_orig = &gps_orig->points[i];
2646  bGPDspoint *pt_eval = &gps_eval->points[i];
2647  pt_orig->runtime.pt_orig = NULL;
2648  pt_orig->runtime.idx_orig = i;
2649  pt_eval->runtime.pt_orig = pt_orig;
2650  pt_eval->runtime.idx_orig = i;
2651  }
2652  /* Increase pointer. */
2653  gps_eval = gps_eval->next;
2654  }
2655  }
2656 }
2657 
2664  const struct bGPDlayer *gpl_eval)
2665 {
2666  bGPDframe *gpf_eval = gpl_eval->frames.first;
2667  LISTBASE_FOREACH (bGPDframe *, gpf_orig, &gpl_orig->frames) {
2668  if (gpf_eval != NULL) {
2669  /* Update frame reference pointers. */
2670  gpf_eval->runtime.gpf_orig = (bGPDframe *)gpf_orig;
2671  BKE_gpencil_frame_original_pointers_update(gpf_orig, gpf_eval);
2672  gpf_eval = gpf_eval->next;
2673  }
2674  }
2675 }
2676 
2677 void BKE_gpencil_data_update_orig_pointers(const bGPdata *gpd_orig, const bGPdata *gpd_eval)
2678 {
2679  /* Assign pointers to the original stroke and points to the evaluated data. This must
2680  * be done before applying any modifier because at this moment the structure is equals,
2681  * so we can assume the layer index is the same in both data-blocks.
2682  * This data will be used by operators. */
2683 
2684  bGPDlayer *gpl_eval = gpd_eval->layers.first;
2685  LISTBASE_FOREACH (bGPDlayer *, gpl_orig, &gpd_orig->layers) {
2686  if (gpl_eval != NULL) {
2687  /* Update layer reference pointers. */
2688  gpl_eval->runtime.gpl_orig = gpl_orig;
2689  BKE_gpencil_layer_original_pointers_update(gpl_orig, gpl_eval);
2690  gpl_eval = gpl_eval->next;
2691  }
2692  }
2693 }
2694 
2700 void BKE_gpencil_update_orig_pointers(const Object *ob_orig, const Object *ob_eval)
2701 {
2703 }
2704 
2706  Object *obact,
2707  bGPDlayer *gpl,
2708  float diff_mat[4][4])
2709 {
2710  Object *ob_eval = depsgraph != NULL ? DEG_get_evaluated_object(depsgraph, obact) : obact;
2711  Object *obparent = gpl->parent;
2712  Object *obparent_eval = depsgraph != NULL ? DEG_get_evaluated_object(depsgraph, obparent) :
2713  obparent;
2714 
2715  /* if not layer parented, try with object parented */
2716  if (obparent_eval == NULL) {
2717  if ((ob_eval != NULL) && (ob_eval->type == OB_GPENCIL)) {
2718  copy_m4_m4(diff_mat, ob_eval->obmat);
2719  mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
2720  return;
2721  }
2722  /* not gpencil object */
2723  unit_m4(diff_mat);
2724  return;
2725  }
2726 
2727  if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
2728  mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
2729  add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
2730  mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
2731  return;
2732  }
2733  if (gpl->partype == PARBONE) {
2734  bPoseChannel *pchan = BKE_pose_channel_find_name(obparent_eval->pose, gpl->parsubstr);
2735  if (pchan) {
2736  float tmp_mat[4][4];
2737  mul_m4_m4m4(tmp_mat, obparent_eval->obmat, pchan->pose_mat);
2738  mul_m4_m4m4(diff_mat, tmp_mat, gpl->inverse);
2739  add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
2740  }
2741  else {
2742  /* if bone not found use object (armature) */
2743  mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
2744  add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
2745  }
2746  mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
2747  return;
2748  }
2749 
2750  unit_m4(diff_mat); /* not defined type */
2751 }
2752 
2754 {
2755  if (ob->type != OB_GPENCIL) {
2756  return;
2757  }
2758 
2759  bGPdata *gpd = (bGPdata *)ob->data;
2760  float cur_mat[4][4];
2761 
2762  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
2763  bool changed = false;
2764  unit_m4(cur_mat);
2765 
2766  /* Skip non-visible layers. */
2767  if (gpl->flag & GP_LAYER_HIDE || is_zero_v3(gpl->scale)) {
2768  continue;
2769  }
2770 
2771  /* Skip empty layers. */
2772  if (BLI_listbase_is_empty(&gpl->frames)) {
2773  continue;
2774  }
2775 
2776  /* Determine frame range to transform. */
2777  bGPDframe *gpf_start = NULL;
2778  bGPDframe *gpf_end = NULL;
2779 
2780  /* If onion skinning is activated, consider all frames. */
2781  if (gpl->onion_flag & GP_LAYER_ONIONSKIN) {
2782  gpf_start = gpl->frames.first;
2783  }
2784  /* Otherwise, consider only active frame. */
2785  else {
2786  /* Skip layer if it has no active frame to transform. */
2787  if (gpl->actframe == NULL) {
2788  continue;
2789  }
2790  gpf_start = gpl->actframe;
2791  gpf_end = gpl->actframe->next;
2792  }
2793 
2794  if (gpl->parent != NULL) {
2795  Object *ob_parent = DEG_get_evaluated_object(depsgraph, gpl->parent);
2796  /* calculate new matrix */
2797  if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
2798  mul_m4_m4m4(cur_mat, ob->imat, ob_parent->obmat);
2799  }
2800  else if (gpl->partype == PARBONE) {
2801  bPoseChannel *pchan = BKE_pose_channel_find_name(ob_parent->pose, gpl->parsubstr);
2802  if (pchan != NULL) {
2803  mul_m4_series(cur_mat, ob->imat, ob_parent->obmat, pchan->pose_mat);
2804  }
2805  else {
2806  unit_m4(cur_mat);
2807  }
2808  }
2809  changed = !equals_m4m4(gpl->inverse, cur_mat);
2810  }
2811 
2812  /* Calc local layer transform. Early out if we have non-animated zero transforms. */
2813  bool transformed = ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) ||
2814  (!is_one_v3(gpl->scale)));
2815  float tmp_mat[4][4];
2816  loc_eul_size_to_mat4(tmp_mat, gpl->location, gpl->rotation, gpl->scale);
2817  transformed |= !equals_m4m4(gpl->layer_mat, tmp_mat);
2818  if (transformed) {
2819  copy_m4_m4(gpl->layer_mat, tmp_mat);
2820  }
2821 
2822  /* Continue if no transformations are applied to this layer. */
2823  if (!changed && !transformed) {
2824  continue;
2825  }
2826 
2827  /* Iterate over frame range. */
2828  for (bGPDframe *gpf = gpf_start; gpf != NULL && gpf != gpf_end; gpf = gpf->next) {
2829  /* Skip frames without a valid onion skinning id (NOTE: active frame has one). */
2830  if (gpf->runtime.onion_id == INT_MAX) {
2831  continue;
2832  }
2833 
2834  /* Apply transformations only if needed. */
2835  if (changed || transformed) {
2836  LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
2837  bGPDspoint *pt;
2838  int i;
2839  for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
2840  if (changed) {
2841  mul_m4_v3(gpl->inverse, &pt->x);
2842  mul_m4_v3(cur_mat, &pt->x);
2843  }
2844 
2845  if (transformed) {
2846  mul_m4_v3(gpl->layer_mat, &pt->x);
2847  }
2848  }
2849  }
2850  }
2851  }
2852  }
2853 }
2854 
2856 {
2857  const int name_prefix_len = strlen(name_prefix);
2858  for (int i = 0; i < ob->totcol; i++) {
2859  Material *ma = BKE_object_material_get(ob, i + 1);
2860  if ((ma != NULL) && (ma->gp_style != NULL) &&
2861  (STREQLEN(ma->id.name + 2, name_prefix, name_prefix_len))) {
2862  return i;
2863  }
2864  }
2865 
2866  return -1;
2867 }
2868 
2870 {
2871  const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
2873 
2874  LISTBASE_FOREACH (bGPDlayer *, gpl_iter, &gpd->layers) {
2875  if ((gpl != NULL) && (!is_multiedit) && (gpl != gpl_iter)) {
2876  continue;
2877  }
2878 
2879  LISTBASE_FOREACH (bGPDframe *, gpf, &gpl_iter->frames) {
2880  if (((gpf == gpl->actframe) && (!is_multiedit)) ||
2881  ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
2882  if (!BLI_ghash_lookup(r_list, POINTER_FROM_INT(gpf->framenum))) {
2883  BLI_ghash_insert(r_list, POINTER_FROM_INT(gpf->framenum), gpf);
2884  }
2885  }
2886  }
2887  }
2888 }
2889 
2891 {
2892  /* For now, we only use the update cache in the active depsgraph. Otherwise we might access the
2893  * cache while another depsgraph frees it. */
2894  if (!DEG_is_active(depsgraph)) {
2895  return false;
2896  }
2897 
2898  GPencilUpdateCache *update_cache = gpd->runtime.update_cache;
2899  return update_cache != NULL && update_cache->flag != GP_UPDATE_NODE_FULL_COPY;
2900 }
2901 
2911 
2913 {
2915  td->gpl_eval = BLI_findlinkfrom((Link *)td->gpl_eval, gpl_cache->index - td->gpl_index);
2916  td->gpl_index = gpl_cache->index;
2917  bGPDlayer *gpl = (bGPDlayer *)gpl_cache->data;
2918 
2919  if (gpl_cache->flag == GP_UPDATE_NODE_FULL_COPY) {
2920  bGPDlayer *gpl_eval_next = td->gpl_eval->next;
2921  BLI_assert(gpl != NULL);
2922 
2924 
2925  td->gpl_eval = BKE_gpencil_layer_duplicate(gpl, true, true);
2926  BLI_insertlinkbefore(&td->gpd_eval->layers, gpl_eval_next, td->gpl_eval);
2927 
2929  td->gpl_eval->runtime.gpl_orig = gpl;
2930  return true;
2931  }
2932  if (gpl_cache->flag == GP_UPDATE_NODE_LIGHT_COPY) {
2933  BLI_assert(gpl != NULL);
2935  td->gpl_eval->runtime.gpl_orig = gpl;
2936  }
2937 
2938  td->gpf_eval = td->gpl_eval->frames.first;
2939  td->gpf_index = 0;
2940  return false;
2941 }
2942 
2944 {
2946  td->gpf_eval = BLI_findlinkfrom((Link *)td->gpf_eval, gpf_cache->index - td->gpf_index);
2947  td->gpf_index = gpf_cache->index;
2948 
2949  bGPDframe *gpf = (bGPDframe *)gpf_cache->data;
2950 
2951  if (gpf_cache->flag == GP_UPDATE_NODE_FULL_COPY) {
2952  /* Do a full copy of the frame. */
2953  bGPDframe *gpf_eval_next = td->gpf_eval->next;
2954  BLI_assert(gpf != NULL);
2955 
2956  bool update_actframe = (td->gpl_eval->actframe == td->gpf_eval) ? true : false;
2958  BLI_freelinkN(&td->gpl_eval->frames, td->gpf_eval);
2959 
2960  td->gpf_eval = BKE_gpencil_frame_duplicate(gpf, true);
2961  BLI_insertlinkbefore(&td->gpl_eval->frames, gpf_eval_next, td->gpf_eval);
2962 
2964  td->gpf_eval->runtime.gpf_orig = gpf;
2965 
2966  if (update_actframe) {
2967  td->gpl_eval->actframe = td->gpf_eval;
2968  }
2969 
2970  return true;
2971  }
2972  if (gpf_cache->flag == GP_UPDATE_NODE_LIGHT_COPY) {
2973  BLI_assert(gpf != NULL);
2975  td->gpf_eval->runtime.gpf_orig = gpf;
2976  }
2977 
2978  td->gps_eval = td->gpf_eval->strokes.first;
2979  td->gps_index = 0;
2980  return false;
2981 }
2982 
2984 {
2986  td->gps_eval = BLI_findlinkfrom((Link *)td->gps_eval, gps_cache->index - td->gps_index);
2987  td->gps_index = gps_cache->index;
2988 
2989  bGPDstroke *gps = (bGPDstroke *)gps_cache->data;
2990 
2991  if (gps_cache->flag == GP_UPDATE_NODE_FULL_COPY) {
2992  /* Do a full copy of the stroke. */
2993  bGPDstroke *gps_eval_next = td->gps_eval->next;
2994  BLI_assert(gps != NULL);
2995 
2996  BLI_remlink(&td->gpf_eval->strokes, td->gps_eval);
2998 
2999  td->gps_eval = BKE_gpencil_stroke_duplicate(gps, true, true);
3000  BLI_insertlinkbefore(&td->gpf_eval->strokes, gps_eval_next, td->gps_eval);
3001 
3002  td->gps_eval->runtime.gps_orig = gps;
3003 
3004  /* Assign original pt pointers. */
3005  for (int i = 0; i < gps->totpoints; i++) {
3006  bGPDspoint *pt_orig = &gps->points[i];
3007  bGPDspoint *pt_eval = &td->gps_eval->points[i];
3008  pt_orig->runtime.pt_orig = NULL;
3009  pt_orig->runtime.idx_orig = i;
3010  pt_eval->runtime.pt_orig = pt_orig;
3011  pt_eval->runtime.idx_orig = i;
3012  }
3013  }
3014  else if (gps_cache->flag == GP_UPDATE_NODE_LIGHT_COPY) {
3015  BLI_assert(gps != NULL);
3017  td->gps_eval->runtime.gps_orig = gps;
3018  }
3019 
3020  return false;
3021 }
3022 
3029 void BKE_gpencil_update_on_write(bGPdata *gpd_orig, bGPdata *gpd_eval)
3030 {
3031  GPencilUpdateCache *update_cache = gpd_orig->runtime.update_cache;
3032 
3033  /* We assume that a full copy is not needed and the update cache is populated. */
3034  if (update_cache == NULL || update_cache->flag == GP_UPDATE_NODE_FULL_COPY) {
3035  return;
3036  }
3037 
3038  if (update_cache->flag == GP_UPDATE_NODE_LIGHT_COPY) {
3039  BKE_gpencil_data_copy_settings(gpd_orig, gpd_eval);
3040  }
3041 
3046  }};
3047 
3049  .gpd_eval = gpd_eval,
3050  .gpl_eval = gpd_eval->layers.first,
3051  .gpf_eval = NULL,
3052  .gps_eval = NULL,
3053  .gpl_index = 0,
3054  .gpf_index = 0,
3055  .gps_index = 0,
3056  };
3057 
3058  BKE_gpencil_traverse_update_cache(update_cache, &ts, &data);
3059 
3060  gpd_eval->flag |= GP_DATA_CACHE_IS_DIRTY;
3061 
3062  /* TODO: This might cause issues when we have multiple depsgraphs? */
3064 }
3065 
typedef float(TangentPoint)[2]
Blender kernel action and pose functionality.
struct bPoseChannel * BKE_pose_channel_find_name(const struct bPose *pose, const char *name)
void BKE_animdata_blend_read_data(struct BlendDataReader *reader, struct AnimData *adt)
Definition: anim_data.c:1443
void BKE_animdata_blend_write(struct BlendWriter *writer, struct AnimData *adt)
Definition: anim_data.c:1421
float BKE_curvemapping_evaluateF(const struct CurveMapping *cumap, int cur, float value)
support for deformation groups and hooks.
int BKE_object_defgroup_active_index_get(const struct Object *ob)
void BKE_defbase_blend_write(struct BlendWriter *writer, const ListBase *defbase)
Definition: deform.c:1557
struct MDeformWeight * BKE_defvert_find_index(const struct MDeformVert *dv, int defgroup)
void BKE_object_defgroup_active_index_set(struct Object *ob, int new_index)
Definition: deform.c:568
void BKE_defgroup_copy_list(struct ListBase *outbase, const struct ListBase *inbase)
void BKE_defvert_blend_write(struct BlendWriter *writer, int count, const struct MDeformVert *dvlist)
void BKE_defvert_array_copy(struct MDeformVert *dst, const struct MDeformVert *src, int totvert)
void BKE_defvert_blend_read(struct BlendDataReader *reader, int count, struct MDeformVert *mdverts)
Definition: deform.c:1581
void BKE_defvert_remove_group(struct MDeformVert *dvert, struct MDeformWeight *dw)
Definition: deform.c:804
void(* gpIterCb)(struct bGPDlayer *layer, struct bGPDframe *frame, struct bGPDstroke *stroke, void *thunk)
Definition: BKE_gpencil.h:654
eGP_GetFrame_Mode
Definition: BKE_gpencil.h:336
@ GP_GETFRAME_ADD_COPY
Definition: BKE_gpencil.h:343
@ GP_GETFRAME_USE_PREV
Definition: BKE_gpencil.h:338
void BKE_gpencil_stroke_geometry_update(struct bGPdata *gpd, struct bGPDstroke *gps)
@ GP_UPDATE_NODE_LIGHT_COPY
@ GP_UPDATE_NODE_FULL_COPY
void BKE_gpencil_free_update_cache(struct bGPdata *gpd)
void BKE_gpencil_traverse_update_cache(GPencilUpdateCache *cache, GPencilUpdateCacheTraverseSettings *ts, void *user_data)
bool BKE_icon_delete(int icon_id)
Definition: icons.cc:888
@ IDTYPE_FLAGS_APPEND_IS_REUSABLE
Definition: BKE_idtype.h:39
void BKE_image_release_ibuf(struct Image *ima, struct ImBuf *ibuf, void *lock)
struct ImBuf * BKE_image_acquire_ibuf(struct Image *ima, struct ImageUser *iuser, void **r_lock)
struct ID * BKE_id_copy(struct Main *bmain, const struct ID *id)
void BKE_libblock_free_data(struct ID *id, bool do_id_user) ATTR_NONNULL()
Definition: lib_id_delete.c:44
void id_us_min(struct ID *id)
Definition: lib_id.c:313
void * BKE_libblock_alloc(struct Main *bmain, short type, const char *name, int flag) ATTR_WARN_UNUSED_RESULT
Definition: lib_id.c:1050
void id_us_plus(struct ID *id)
Definition: lib_id.c:305
void BKE_id_blend_write(struct BlendWriter *writer, struct ID *id)
Definition: lib_id.c:2008
#define BKE_LIB_FOREACHID_PROCESS_IDSUPER(_data, _id_super, _cb_flag)
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:73
@ IDWALK_CB_NOP
Definition: BKE_lib_query.h:33
General operations, lookup, etc. for materials.
struct MaterialGPencilStyle * BKE_gpencil_material_settings(struct Object *ob, short act)
Definition: material.c:805
struct Material * BKE_object_material_get(struct Object *ob, short act)
Definition: material.c:687
struct Material * BKE_gpencil_material(struct Object *ob, short act)
Definition: material.c:795
struct Material * BKE_gpencil_material_add(struct Main *bmain, const char *name)
Definition: material.c:298
void BKE_object_material_assign(struct Main *bmain, struct Object *ob, struct Material *ma, short act, int assign_type)
Definition: material.c:1047
struct Material * BKE_material_default_gpencil(void)
Definition: material.c:2061
void BKE_gpencil_material_attr_init(struct Material *ma)
Definition: material.c:270
bool BKE_object_material_slot_add(struct Main *bmain, struct Object *ob)
Definition: material.c:1232
short * BKE_object_material_len_p(struct Object *ob)
Definition: material.c:344
@ BKE_MAT_ASSIGN_USERPREF
Definition: BKE_material.h:80
struct Palette * BKE_palette_add(struct Main *bmain, const char *name)
Definition: paint.c:764
void BKE_paint_palette_set(struct Paint *p, struct Palette *palette)
Definition: paint.c:719
struct PaletteColor * BKE_palette_color_add(struct Palette *palette)
Definition: paint.c:770
#define BLI_assert(a)
Definition: BLI_assert.h:46
bool BLI_ghash_haskey(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:822
GHash * BLI_ghash_int_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:734
unsigned int BLI_ghash_len(const GHash *gh) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:705
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:710
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:60
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:239
#define LISTBASE_FOREACH_MUTABLE(type, var, list)
Definition: BLI_listbase.h:354
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:301
void * BLI_findlinkfrom(struct Link *start, int number) ATTR_WARN_UNUSED_RESULT
Definition: listbase.c:534
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:466
void void BLI_listbase_sort(struct ListBase *listbase, int(*cmp)(const void *, const void *)) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:100
int BLI_findindex(const struct ListBase *listbase, const void *vlink) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1)
Definition: listbase.c:340
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void void void BLI_listbase_sort_r(ListBase *listbase, int(*cmp)(void *, const void *, const void *), void *thunk) ATTR_NONNULL(1
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int compare_ff(float a, float b, float max_diff)
void rgb_to_hsv_compat_v(const float rgb[3], float r_hsv[3])
Definition: math_color.c:318
void hex_to_rgb(const char *hexcol, float *r_r, float *r_g, float *r_b)
Definition: math_color.c:177
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:259
void unit_m4(float m[4][4])
Definition: rct.c:1090
bool invert_m4_m4(float R[4][4], const float A[4][4])
Definition: math_matrix.c:1287
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:729
#define mul_m4_series(...)
bool equals_m4m4(const float mat1[4][4], const float mat2[4][4])
Definition: math_matrix.c:2531
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
void loc_eul_size_to_mat4(float R[4][4], const float loc[3], const float eul[3], const float size[3])
Definition: math_matrix.c:2547
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v2_v2_short(short r[2], const short a[2])
MINLINE bool is_one_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_fl(float r[3], float f)
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE void copy_v2_fl(float r[2], float f)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
bool BLI_uniquename(struct ListBase *list, void *vlink, const char *defname, char delim, int name_offset, size_t name_len)
Definition: string_utils.c:309
#define ARRAY_SIZE(arr)
#define ARRAY_SET_ITEMS(...)
#define STREQLEN(a, b, n)
#define POINTER_FROM_INT(i)
#define UNUSED(x)
#define POINTER_AS_INT(i)
#define ELEM(...)
#define STREQ(a, b)
#define CLAMP_MIN(a, b)
#define BLO_read_data_address(reader, ptr_p)
#define BLO_write_id_struct(writer, struct_name, id_address, id)
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_list(BlendDataReader *reader, struct ListBase *list)
Definition: readfile.c:5172
#define BLO_read_id_address(reader, lib, id_ptr_p)
#define BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
#define BLO_expand(expander, id)
#define BLO_write_struct_list(writer, struct_name, list_ptr)
void BLO_read_pointer_array(BlendDataReader *reader, void **ptr_p)
Definition: readfile.c:5245
void BLO_write_pointer_array(BlendWriter *writer, uint num, const void *data_ptr)
Definition: writefile.c:1591
#define BLT_I18NCONTEXT_ID_GPENCIL
#define DATA_(msgid)
#define CLOG_ERROR(clg_ref,...)
Definition: CLG_log.h:190
#define CLOG_STR_ERROR(clg_ref, str)
Definition: CLG_log.h:196
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:35
bool DEG_is_active(const struct Depsgraph *depsgraph)
Definition: depsgraph.cc:312
void DEG_id_tag_update(struct ID *id, int flag)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
@ ID_RECALC_TRANSFORM
Definition: DNA_ID.h:771
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:791
@ INDEX_ID_GD
Definition: DNA_ID.h:990
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
#define FILTER_ID_GD
Definition: DNA_ID.h:904
@ ID_GD
Definition: DNA_ID_enums.h:71
@ GP_BRUSH_MATERIAL_PINNED
#define BEZT_ISSEL_ANY(bezt)
@ GP_ONION_MODE_RELATIVE
@ GP_ONION_MODE_SELECTED
@ GP_ONION_MODE_ABSOLUTE
#define GP_DEFAULT_CURVE_EDIT_CORNER_ANGLE
#define GP_DEFAULT_PIX_FACTOR
#define GPENCIL_PLAY_ON(gpd)
@ GP_CURVE_SELECT
@ GP_STROKE_SELECT
@ GP_STROKE_3DSPACE
#define GP_DEFAULT_CURVE_RESOLUTION
#define GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)
#define GPENCIL_PAINT_MODE(gpd)
struct bGPdata bGPdata
@ GP_LAYER_SOLO_MODE
@ GP_LAYER_DISABLE_MASKS_IN_VIEWLAYER
@ GP_LAYER_LOCKED
@ GP_LAYER_FRAMELOCK
@ GP_LAYER_ACTIVE
@ GP_LAYER_UNLOCK_COLOR
@ GP_LAYER_HIDE
@ GP_LAYER_USE_LIGHTS
#define GP_DEFAULT_GRID_LINES
@ GP_LAYER_ONIONSKIN
#define GP_DEFAULT_CURVE_ERROR
@ GP_ONION_GHOST_NEXTCOL
@ GP_ONION_GHOST_PREVCOL
@ GP_ONION_FADE
@ GP_ONION_LOOP
@ GP_FRAME_SELECT
@ GP_FRAME_PAINT
@ GP_DATA_SHOW_ONIONSKINS
@ GP_DATA_VIEWALIGN
@ GP_DATA_CURVE_ADAPTIVE_RESOLUTION
@ GP_DATA_STROKE_WEIGHTMODE
@ GP_DATA_EXPAND
@ GP_DATA_DISPINFO
@ GP_DATA_STROKE_VERTEXMODE
@ GP_DATA_CACHE_IS_DIRTY
@ GP_DATA_STROKE_PAINTMODE
@ GP_DATA_STROKE_SCULPTMODE
@ GP_DATA_AUTOLOCK_LAYERS
@ GP_DATA_ANNOTATIONS
@ GP_DATA_STROKE_EDITMODE
@ GP_SPOINT_SELECT
@ GP_MATERIAL_LOCKED
@ GP_MATERIAL_HIDE
@ GP_MATERIAL_STROKE_SHOW
@ GP_MATERIAL_FILL_SHOW
@ OB_GPENCIL
@ PARSKEL
@ PAROBJECT
@ PARBONE
void IMB_sampleImageAtLocation(struct ImBuf *ibuf, float x, float y, bool make_linear_rgb, float color[4])
Definition: imageprocess.c:484
Contains defines and structs used throughout the imbuf module.
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
static void init_data(ModifierData *md)
static float frame_len(const Frame *frame)
Definition: MOD_skin.c:379
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
volatile int lock
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
unsigned int U
Definition: btGjkEpa3.h:78
Scene scene
Material material
const Depsgraph * depsgraph
void * user_data
SyclQueue void void size_t num_bytes void
depth_tx normal_tx diffuse_light_tx specular_light_tx volume_light_tx environment_tx ambient_occlusion_tx aov_value_tx in_weight_img image(1, GPU_R32F, Qualifier::WRITE, ImageType::FLOAT_2D_ARRAY, "out_weight_img") .image(3
void BKE_gpencil_update_on_write(bGPdata *gpd_orig, bGPdata *gpd_eval)
Definition: gpencil.c:3029
static bool gpencil_update_on_write_layer_cb(GPencilUpdateCache *gpl_cache, void *user_data)
Definition: gpencil.c:2912
Material * BKE_gpencil_object_material_ensure_from_active_input_toolsettings(Main *bmain, Object *ob, ToolSettings *ts)
Definition: gpencil.c:1768
static bool gpencil_update_on_write_stroke_cb(GPencilUpdateCache *gps_cache, void *user_data)
Definition: gpencil.c:2983
void BKE_gpencil_tag(bGPdata *gpd)
Definition: gpencil.c:506
bool BKE_gpencil_merge_materials_table_get(Object *ob, const float hue_threshold, const float sat_threshold, const float val_threshold, GHash *r_mat_table)
Definition: gpencil.c:2003
void BKE_gpencil_free_stroke_weights(bGPDstroke *gps)
Definition: gpencil.c:361
bool BKE_gpencil_stroke_select_check(const bGPDstroke *gps)
Definition: gpencil.c:1825
bGPDcurve * BKE_gpencil_stroke_editcurve_new(const int tot_curve_points)
Definition: gpencil.c:821
bGPDlayer * BKE_gpencil_layer_active_get(bGPdata *gpd)
Definition: gpencil.c:1558
bGPDlayer * BKE_gpencil_layer_addnew(bGPdata *gpd, const char *name, const bool setactive, const bool add_to_header)
Definition: gpencil.c:621
void BKE_gpencil_frame_range_selected(bGPDlayer *gpl, int *r_initframe, int *r_endframe)
Definition: gpencil.c:1900
void BKE_gpencil_layer_mask_copy(const bGPDlayer *gpl_src, bGPDlayer *gpl_dst)
Definition: gpencil.c:1506
void BKE_gpencil_stats_update(bGPdata *gpd)
Definition: gpencil.c:2180
int BKE_gpencil_object_material_get_index_from_brush(Object *ob, Brush *brush)
Definition: gpencil.c:1759
void BKE_gpencil_stroke_copy_settings(const bGPDstroke *gps_src, bGPDstroke *gps_dst)
Definition: gpencil.c:1041
void BKE_gpencil_batch_cache_free(bGPdata *gpd)
Definition: gpencil.c:343
void BKE_gpencil_layer_mask_cleanup_all_layers(bGPdata *gpd)
Definition: gpencil.c:1525
void BKE_gpencil_material_remap(struct bGPdata *gpd, const unsigned int *remap, unsigned int remap_len)
Definition: gpencil.c:1978
void BKE_gpencil_layer_copy_settings(const bGPDlayer *gpl_src, bGPDlayer *gpl_dst)
Definition: gpencil.c:1012
void BKE_gpencil_free_frames(bGPDlayer *gpl)
Definition: gpencil.c:427
static int gpencil_cb_sort_masks(const void *arg1, const void *arg2)
Definition: gpencil.c:1467
Material * BKE_gpencil_object_material_ensure_by_name(Main *bmain, Object *ob, const char *name, int *r_index)
Definition: gpencil.c:2228
void BKE_gpencil_free_point_weights(MDeformVert *dvert)
Definition: gpencil.c:353
static bool gpencil_is_layer_mask(ViewLayer *view_layer, bGPdata *gpd, bGPDlayer *gpl_mask)
Definition: gpencil.c:2361
static void greasepencil_blend_read_lib(BlendLibReader *reader, ID *id)
Definition: gpencil.c:270
void BKE_gpencil_layer_mask_remove(bGPDlayer *gpl, bGPDlayer_Mask *mask)
Definition: gpencil.c:1446
bool BKE_gpencil_layer_is_editable(const bGPDlayer *gpl)
Definition: gpencil.c:1200
void(* BKE_gpencil_batch_cache_dirty_tag_cb)(bGPdata *gpd)
Definition: gpencil.c:332
struct tGPencilUpdateOnWriteTraverseData tGPencilUpdateOnWriteTraverseData
bool BKE_gpencil_can_avoid_full_copy_on_write(const Depsgraph *depsgraph, bGPdata *gpd)
Definition: gpencil.c:2890
void BKE_gpencil_free_stroke_editcurve(bGPDstroke *gps)
Definition: gpencil.c:377
Material * BKE_gpencil_object_material_ensure_active(Object *ob)
Definition: gpencil.c:1807
void BKE_gpencil_layer_autolock_set(bGPdata *gpd, const bool unlock)
Definition: gpencil.c:1623
#define MAT_NR_REMAP(n)
void BKE_gpencil_free_layers(ListBase *list)
Definition: gpencil.c:456
void BKE_gpencil_layer_frames_sort(struct bGPDlayer *gpl, bool *r_has_duplicate_frames)
Definition: gpencil.c:1553
void BKE_gpencil_stroke_weights_duplicate(bGPDstroke *gps_src, bGPDstroke *gps_dst)
Definition: gpencil.c:834
static void greasepencil_blend_write(BlendWriter *writer, ID *id, const void *id_address)
Definition: gpencil.c:133
static void greasepencil_free_data(ID *id)
Definition: gpencil.c:113
bool BKE_gpencil_free_strokes(bGPDframe *gpf)
Definition: gpencil.c:414
Material * BKE_gpencil_object_material_ensure_from_brush(Main *bmain, Object *ob, Brush *brush)
Definition: gpencil.c:1702
Material * BKE_gpencil_object_material_ensure_from_active_input_material(Object *ob)
Definition: gpencil.c:1797
void BKE_gpencil_layer_original_pointers_update(const struct bGPDlayer *gpl_orig, const struct bGPDlayer *gpl_eval)
Definition: gpencil.c:2663
void BKE_gpencil_material_index_reassign(bGPdata *gpd, int totcol, int index)
Definition: gpencil.c:1948
bGPDstroke * BKE_gpencil_stroke_new(int mat_idx, int totpoints, short thickness)
Definition: gpencil.c:756
void BKE_gpencil_visible_stroke_iter(bGPdata *gpd, gpIterCb layer_cb, gpIterCb stroke_cb, void *thunk)
Definition: gpencil.c:2389
void BKE_gpencil_frame_copy_settings(const bGPDframe *gpf_src, bGPDframe *gpf_dst)
Definition: gpencil.c:1034
void BKE_gpencil_palette_ensure(Main *bmain, Scene *scene)
Definition: gpencil.c:2241
Material * BKE_gpencil_object_material_from_brush_get(Object *ob, Brush *brush)
Definition: gpencil.c:1748
void BKE_gpencil_visible_stroke_advanced_iter(ViewLayer *view_layer, Object *ob, gpIterCb layer_cb, gpIterCb stroke_cb, void *thunk, bool do_onion, int cfra)
Definition: gpencil.c:2430
int BKE_gpencil_object_material_ensure(Main *bmain, Object *ob, Material *material)
Definition: gpencil.c:1720
void BKE_gpencil_free_layer_masks(bGPDlayer *gpl)
Definition: gpencil.c:447
void BKE_gpencil_frame_copy_strokes(bGPDframe *gpf_src, struct bGPDframe *gpf_dst)
Definition: gpencil.c:920
void BKE_gpencil_stroke_sync_selection(bGPdata *gpd, bGPDstroke *gps)
Definition: gpencil.c:1092
void BKE_gpencil_dvert_ensure(bGPDstroke *gps)
Definition: gpencil.c:1891
static int gpencil_cb_cmp_frame(void *thunk, const void *a, const void *b)
Definition: gpencil.c:1532
void BKE_gpencil_update_layer_transforms(const Depsgraph *depsgraph, Object *ob)
Definition: gpencil.c:2753
int BKE_gpencil_object_material_index_get_by_name(Object *ob, const char *name)
Definition: gpencil.c:2213
bool BKE_gpencil_from_image(SpaceImage *sima, bGPdata *gpd, bGPDframe *gpf, const float size, const bool mask)
Definition: gpencil.c:2290
void(* BKE_gpencil_batch_cache_free_cb)(bGPdata *gpd)
Definition: gpencil.c:333
bGPDlayer * BKE_gpencil_layer_named_get(bGPdata *gpd, const char *name)
Definition: gpencil.c:1419
bGPDframe * BKE_gpencil_frame_addnew(bGPDlayer *gpl, int cframe)
Definition: gpencil.c:514
void BKE_gpencil_frame_delete_laststroke(bGPDlayer *gpl, bGPDframe *gpf)
Definition: gpencil.c:1169
bGPDlayer_Mask * BKE_gpencil_layer_mask_add(bGPDlayer *gpl, const char *name)
Definition: gpencil.c:1435
bGPDframe * BKE_gpencil_frame_duplicate(const bGPDframe *gpf_src, const bool dup_strokes)
Definition: gpencil.c:892
void BKE_gpencil_frame_original_pointers_update(const struct bGPDframe *gpf_orig, const struct bGPDframe *gpf_eval)
Definition: gpencil.c:2630
static void greasepencil_copy_data(Main *UNUSED(bmain), ID *id_dst, const ID *id_src, const int UNUSED(flag))
Definition: gpencil.c:60
void BKE_gpencil_update_orig_pointers(const Object *ob_orig, const Object *ob_eval)
Definition: gpencil.c:2700
bGPDframe * BKE_gpencil_layer_frame_find(bGPDlayer *gpl, int cframe)
Definition: gpencil.c:1216
void BKE_gpencil_stroke_select_index_reset(bGPDstroke *gps)
Definition: gpencil.c:1161
static void greasepencil_foreach_id(ID *id, LibraryForeachIDData *data)
Definition: gpencil.c:120
void BKE_gpencil_layer_mask_remove_ref(bGPdata *gpd, const char *name)
Definition: gpencil.c:1453
bGPDframe * BKE_gpencil_frame_addcopy(bGPDlayer *gpl, int cframe)
Definition: gpencil.c:567
void BKE_gpencil_batch_cache_dirty_tag(bGPdata *gpd)
Definition: gpencil.c:335
void BKE_gpencil_blend_read_data(BlendDataReader *reader, bGPdata *gpd)
Definition: gpencil.c:183
Material * BKE_gpencil_object_material_new(Main *bmain, Object *ob, const char *name, int *r_index)
Definition: gpencil.c:1734
bool BKE_gpencil_layer_frame_delete(bGPDlayer *gpl, bGPDframe *gpf)
Definition: gpencil.c:1396
bGPDlayer * BKE_gpencil_layer_get_by_name(bGPdata *gpd, char *name, int first_if_not_found)
Definition: gpencil.c:1576
float BKE_gpencil_multiframe_falloff_calc(bGPDframe *gpf, int actnum, int f_init, int f_end, CurveMapping *cur_falloff)
Definition: gpencil.c:1917
bool BKE_gpencil_merge_materials(Object *ob, const float hue_threshold, const float sat_threshold, const float val_threshold, int *r_removed)
Definition: gpencil.c:2122
void BKE_gpencil_layer_transform_matrix_get(const Depsgraph *depsgraph, Object *obact, bGPDlayer *gpl, float diff_mat[4][4])
Definition: gpencil.c:2705
int BKE_gpencil_material_find_index_by_name_prefix(Object *ob, const char *name_prefix)
Definition: gpencil.c:2855
bGPdata * BKE_gpencil_data_addnew(Main *bmain, const char name[])
Definition: gpencil.c:705
bGPDlayer_Mask * BKE_gpencil_layer_mask_named_get(bGPDlayer *gpl, const char *name)
Definition: gpencil.c:1427
void BKE_gpencil_stroke_select_index_set(bGPdata *gpd, bGPDstroke *gps)
Definition: gpencil.c:1155
void BKE_gpencil_layer_mask_sort_all(bGPdata *gpd)
Definition: gpencil.c:1499
bGPDstroke * BKE_gpencil_stroke_add(bGPDframe *gpf, int mat_idx, int totpoints, short thickness, const bool insert_at_head)
Definition: gpencil.c:792
void BKE_gpencil_eval_delete(bGPdata *gpd_eval)
Definition: gpencil.c:498
IDTypeInfo IDType_ID_GD
Definition: gpencil.c:299
static CLG_LogRef LOG
Definition: gpencil.c:58
Material * BKE_gpencil_brush_material_get(Brush *brush)
Definition: gpencil.c:1675
static void greasepencil_blend_read_expand(BlendExpander *expander, ID *id)
Definition: gpencil.c:287
void BKE_gpencil_layer_mask_cleanup(bGPdata *gpd, bGPDlayer *gpl)
Definition: gpencil.c:1516
int BKE_gpencil_object_material_index_get(Object *ob, Material *ma)
Definition: gpencil.c:2199
void BKE_gpencil_data_copy_settings(const bGPdata *gpd_src, bGPdata *gpd_dst)
Definition: gpencil.c:975
void BKE_gpencil_frame_selected_hash(bGPdata *gpd, struct GHash *r_list)
Definition: gpencil.c:2869
void BKE_gpencil_data_update_orig_pointers(const bGPdata *gpd_orig, const bGPdata *gpd_eval)
Definition: gpencil.c:2677
void BKE_gpencil_vgroup_remove(Object *ob, bDeformGroup *defgroup)
Definition: gpencil.c:1840
bGPDcurve * BKE_gpencil_stroke_curve_duplicate(bGPDcurve *gpc_src)
Definition: gpencil.c:844
void BKE_gpencil_free_data(bGPdata *gpd, bool free_all)
Definition: gpencil.c:479
void BKE_gpencil_free_stroke(bGPDstroke *gps)
Definition: gpencil.c:391
bGPDstroke * BKE_gpencil_stroke_add_existing_style(bGPDframe *gpf, bGPDstroke *existing, int mat_idx, int totpoints, short thickness)
Definition: gpencil.c:810
bGPdata * BKE_gpencil_data_duplicate(Main *bmain, const bGPdata *gpd_src, bool internal_copy)
Definition: gpencil.c:1060
void BKE_gpencil_curve_sync_selection(bGPdata *gpd, bGPDstroke *gps)
Definition: gpencil.c:1120
void BKE_gpencil_brush_material_set(Brush *brush, Material *ma)
Definition: gpencil.c:1687
static bool gpencil_update_on_write_frame_cb(GPencilUpdateCache *gpf_cache, void *user_data)
Definition: gpencil.c:2943
static void greasepencil_blend_read_data(BlendDataReader *reader, ID *id)
Definition: gpencil.c:264
void BKE_gpencil_layer_active_set(bGPdata *gpd, bGPDlayer *active)
Definition: gpencil.c:1601
bool BKE_gpencil_material_index_used(bGPdata *gpd, int index)
Definition: gpencil.c:1963
Material * BKE_gpencil_object_material_ensure_from_active_input_brush(Main *bmain, Object *ob, Brush *brush)
Definition: gpencil.c:1780
void BKE_gpencil_layer_mask_sort(bGPdata *gpd, bGPDlayer *gpl)
Definition: gpencil.c:1484
bGPDstroke * BKE_gpencil_stroke_duplicate(bGPDstroke *gps_src, const bool dup_points, const bool dup_curve)
Definition: gpencil.c:855
bGPDframe * BKE_gpencil_layer_frame_get(bGPDlayer *gpl, int cframe, eGP_GetFrame_Mode addnew)
Definition: gpencil.c:1232
bGPDlayer * BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src, const bool dup_frames, const bool dup_strokes)
Definition: gpencil.c:937
void BKE_gpencil_layer_delete(bGPdata *gpd, bGPDlayer *gpl)
Definition: gpencil.c:1653
uint col
const int state
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_dupallocN)(const void *vmemh)
Definition: mallocn.c:28
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
static unsigned a[3]
Definition: RandGen.cpp:78
bool active
all scheduled work for the GPU.
T abs(const T &a)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
static const pxr::TfToken g("g", pxr::TfToken::Immortal)
struct Material * material
struct BrushGpencilSettings * gpencil_settings
short id_code
Definition: BKE_idtype.h:114
Definition: DNA_ID.h:368
void * py_instance
Definition: DNA_ID.h:435
struct Library * lib
Definition: DNA_ID.h:372
char name[66]
Definition: DNA_ID.h:378
unsigned int * rect
struct Library * parent
Definition: DNA_ID.h:474
void * last
Definition: DNA_listBase.h:31
void * first
Definition: DNA_listBase.h:31
struct MDeformWeight * dw
unsigned int def_nr
Definition: BKE_main.h:121
ListBase palettes
Definition: BKE_main.h:195
struct MaterialGPencilStyle * gp_style
struct bPose * pose
float imat[4][4]
float obmat[4][4]
void * data
struct Palette * palette
struct Brush * brush
struct ToolSettings * toolsettings
struct ImageUser iuser
struct Image * image
GpPaint * gp_paint
GpVertexPaint * gp_vertexpaint
char name[64]
bGPDcurve_point * curve_points
struct bGPDframe * gpf_orig
struct bGPDframe * next
bGPDframe_Runtime runtime
ListBase strokes
struct bGPDframe * prev
struct bGPDlayer_Mask * prev
struct bGPDlayer_Mask * next
struct bGPDlayer * gpl_orig
float inverse[4][4]
float gcolor_next[3]
struct Object * parent
float color[4]
char info[128]
float tintcolor[4]
struct bGPDlayer * next
bGPDframe * actframe
float layer_mat[4][4]
char parsubstr[64]
char viewlayername[64]
bGPDlayer_Runtime runtime
float layer_invmat[4][4]
ListBase frames
float vertex_paint_opacity
ListBase mask_layers
float gcolor_prev[3]
float rotation[3]
float scale[3]
float location[3]
struct bGPDlayer * prev
struct bGPDspoint * pt_orig
bGPDspoint_Runtime runtime
float vert_color[4]
struct bGPDstroke * gps_orig
struct bGPDstroke * prev
bGPDspoint * points
float uv_translation[2]
float fill_opacity_fac
float aspect_ratio[2]
float vert_color_fill[4]
bGPDtriangle * triangles
bGPDstroke_Runtime runtime
float boundbox_max[3]
float boundbox_min[3]
struct bGPDcurve * editcurve
struct MDeformVert * dvert
struct bGPDstroke * next
struct GPencilUpdateCache * update_cache
ListBase vertex_group_names
float zdepth_offset
float curve_edit_corner_angle
int curve_edit_resolution
int select_last_index
float gcolor_prev[3]
float line_color[4]
ListBase layers
short gstep_next
float gcolor_next[3]
int vertex_group_active_index
float curve_edit_threshold
bGPgrid grid
struct Material ** mat
short onion_keytype
float onion_factor
bGPdata_Runtime runtime
struct AnimData * adt
float scale[2]
float color[3]
float offset[2]
float pose_mat[4][4]