Blender  V3.3
gpencil_modifier.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2017 Blender Foundation. */
3 
8 #include <stdio.h>
9 
10 #include "MEM_guardedalloc.h"
11 
12 #include "BLI_blenlib.h"
13 #include "BLI_math_geom.h"
14 #include "BLI_math_vector.h"
15 #include "BLI_string_utils.h"
16 #include "BLI_utildefines.h"
17 
18 #include "BLT_translation.h"
19 
20 #include "DNA_armature_types.h"
22 #include "DNA_gpencil_types.h"
23 #include "DNA_mesh_types.h"
24 #include "DNA_meshdata_types.h"
25 #include "DNA_modifier_types.h"
26 #include "DNA_object_types.h"
27 #include "DNA_scene_types.h"
28 #include "DNA_screen_types.h"
29 
30 #include "BKE_colortools.h"
31 #include "BKE_deform.h"
32 #include "BKE_gpencil.h"
33 #include "BKE_gpencil_geom.h"
34 #include "BKE_gpencil_modifier.h"
35 #include "BKE_lattice.h"
36 #include "BKE_lib_id.h"
37 #include "BKE_lib_query.h"
38 #include "BKE_material.h"
39 #include "BKE_modifier.h"
40 #include "BKE_object.h"
41 #include "BKE_shrinkwrap.h"
42 
43 #include "DEG_depsgraph.h"
44 #include "DEG_depsgraph_query.h"
45 
46 #include "MOD_gpencil_lineart.h"
48 
49 #include "BLO_read_write.h"
50 
51 #include "CLG_log.h"
52 
53 static CLG_LogRef LOG = {"bke.gpencil_modifier"};
55 #if 0
56 /* Note that GPencil actually does not support these at the moment, but might do in the future. */
58 #endif
59 
60 /* Lattice Modifier ---------------------------------- */
61 /* Usually, evaluation of the lattice modifier is self-contained.
62  * However, since GP's modifiers operate on a per-stroke basis,
63  * we need to these two extra functions that called before/after
64  * each loop over all the geometry being evaluated.
65  */
66 
68 {
70  switch (md->type) {
73  Object *latob = NULL;
74 
75  latob = mmd->object;
76  if ((!latob) || (latob->type != OB_LATTICE)) {
77  return;
78  }
79  if (mmd->cache_data) {
81  }
82 
83  /* init deform data */
85  break;
86  }
89  ob = mmd->target;
90  if (!ob) {
91  return;
92  }
93  if (mmd->cache_data) {
96  }
97  Object *ob_target = DEG_get_evaluated_object(depsgraph, ob);
99  mmd->cache_data = MEM_callocN(sizeof(ShrinkwrapTreeData), __func__);
101  mmd->cache_data, target, mmd->shrink_type, mmd->shrink_mode, false)) {
102  }
103  else {
105  }
106  break;
107  }
108 
109  default:
110  break;
111  }
112  }
113 }
114 
116 {
118  switch (md->type) {
121  if ((mmd) && (mmd->cache_data)) {
123  mmd->cache_data = NULL;
124  }
125  break;
126  }
129  if ((mmd) && (mmd->cache_data)) {
132  }
133  break;
134  }
135  default:
136  break;
137  }
138  }
139 }
140 
141 /* *************************************************** */
142 /* Modifier Methods - Evaluation Loops, etc. */
143 
145  const Object *ob, GpencilVirtualModifierData *UNUSED(virtualModifierData))
146 {
148 
149 #if 0
150  /* Note that GPencil actually does not support these at the moment,
151  * but might do in the future. */
152  *virtualModifierData = virtualModifierCommonData;
153  if (ob->parent) {
154  if (ob->parent->type == OB_ARMATURE && ob->partype == PARSKEL) {
155  virtualModifierData->amd.object = ob->parent;
156  virtualModifierData->amd.modifier.next = md;
157  virtualModifierData->amd.deformflag = ((bArmature *)(ob->parent->data))->deformflag;
158  md = &virtualModifierData->amd.modifier;
159  }
160  else if (ob->parent->type == OB_LATTICE && ob->partype == PARSKEL) {
161  virtualModifierData->lmd.object = ob->parent;
162  virtualModifierData->lmd.modifier.next = md;
163  md = &virtualModifierData->lmd.modifier;
164  }
165  }
166 #endif
167 
168  return md;
169 }
170 
172 {
175 
176  if (mti && mti->generateStrokes) {
177  return true;
178  }
179  }
180  return false;
181 }
182 
184 {
187 
188  if (mti && mti->remapTime) {
189  return true;
190  }
191  }
192  return false;
193 }
194 
196 {
198  /* Only if enabled in edit mode. */
199  if (!GPENCIL_MODIFIER_EDIT(md, true) && GPENCIL_MODIFIER_ACTIVE(md, false)) {
200  if (ELEM(md->type,
205  return true;
206  }
207  }
208  }
209  return false;
210 }
211 
213 {
214  GpencilLineartLimitInfo info = {0};
215  bool is_first = true;
217  if (md->type == eGpencilModifierType_Lineart) {
219  if (is_first || (lmd->flags & LRT_GPENCIL_USE_CACHE)) {
220  info.min_level = MIN2(info.min_level, lmd->level_start);
221  info.max_level = MAX2(info.max_level,
222  (lmd->use_multiple_levels ? lmd->level_end : lmd->level_start));
223  info.edge_types |= lmd->edge_types;
226  is_first = false;
227  }
228  }
229  }
230  return info;
231 }
232 
234  const GpencilLineartLimitInfo *info,
235  const bool is_first_lineart)
236 {
239  if (is_first_lineart || lmd->flags & LRT_GPENCIL_USE_CACHE) {
240  lmd->level_start_override = info->min_level;
241  lmd->level_end_override = info->max_level;
242  lmd->edge_types_override = info->edge_types;
245  }
246  else {
247  lmd->level_start_override = lmd->level_start;
248  lmd->level_end_override = lmd->level_end;
249  lmd->edge_types_override = lmd->edge_types;
252  }
253 }
254 
256 {
257  if (md->type != eGpencilModifierType_Lineart) {
258  return false;
259  }
261  if (gmd->type == eGpencilModifierType_Lineart) {
262  if (gmd == md) {
263  return true;
264  }
265  return false;
266  }
267  }
268  /* If we reach here it means md is not in ob's modifier stack. */
269  BLI_assert(false);
270  return false;
271 }
272 
274  Scene *scene,
275  Object *ob,
276  bGPDlayer *gpl,
277  const int cfra,
278  const bool is_render)
279 {
280  bGPdata *gpd = ob->data;
281  const bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd);
282  int nfra = cfra;
283 
285  if (GPENCIL_MODIFIER_ACTIVE(md, is_render)) {
287 
288  if (GPENCIL_MODIFIER_EDIT(md, is_edit) && (!is_render)) {
289  continue;
290  }
291 
292  if (mti->remapTime) {
293  nfra = mti->remapTime(md, depsgraph, scene, ob, gpl, cfra);
294  /* if the frame number changed, don't evaluate more and return */
295  if (nfra != cfra) {
296  return nfra;
297  }
298  }
299  }
300  }
301 
302  /* if no time modifier, return original frame number */
303  return nfra;
304 }
305 
307 {
308  DEG_debug_print_eval(depsgraph, __func__, gpd->id.name, gpd);
309  int ctime = (int)DEG_get_ctime(depsgraph);
310 
311  /* update active frame */
312  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
313  gpl->actframe = BKE_gpencil_layer_frame_get(gpl, ctime, GP_GETFRAME_USE_PREV);
314  }
315 
316  if (DEG_is_active(depsgraph)) {
317  bGPdata *gpd_orig = (bGPdata *)DEG_get_original_id(&gpd->id);
318 
319  /* sync "actframe" changes back to main-db too,
320  * so that editing tools work with copy-on-write
321  * when the current frame changes
322  */
323  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_orig->layers) {
324  gpl->actframe = BKE_gpencil_layer_frame_get(gpl, ctime, GP_GETFRAME_USE_PREV);
325  }
326  }
327 }
328 
330 {
331  /* Initialize modifier types */
332  gpencil_modifier_type_init(modifier_gpencil_types); /* MOD_gpencil_util.c */
333 
334 #if 0
335  /* Note that GPencil actually does not support these at the moment,
336  * but might do in the future. */
337  /* Initialize global common storage used for virtual modifier list. */
342 
346 
349 #endif
350 }
351 
353 {
356 
357  /* NOTE: this name must be made unique later. */
358  BLI_strncpy(md->name, DATA_(mti->name), sizeof(md->name));
359 
360  md->type = type;
363  md->ui_expand_flag = 1; /* Only expand the parent panel at first. */
364 
367  }
368 
369  if (mti->initData) {
370  mti->initData(md);
371  }
372 
373  return md;
374 }
375 
376 static void modifier_free_data_id_us_cb(void *UNUSED(userData),
377  Object *UNUSED(ob),
378  ID **idpoin,
379  int cb_flag)
380 {
381  ID *id = *idpoin;
382  if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
383  id_us_min(id);
384  }
385 }
386 
388 {
390 
391  if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
392  if (mti->foreachIDLink) {
394  }
395  }
396 
397  if (mti->freeData) {
398  mti->freeData(md);
399  }
400  if (md->error) {
401  MEM_freeN(md->error);
402  }
403 
404  MEM_freeN(md);
405 }
406 
408 {
410 }
411 
413 {
414  if (modifiers && gmd) {
416  return BLI_uniquename(modifiers,
417  gmd,
418  DATA_(gmti->name),
419  '.',
420  offsetof(GpencilModifierData, name),
421  sizeof(gmd->name));
422  }
423  return false;
424 }
425 
427 {
429 
430  return mti->dependsOnTime && mti->dependsOnTime(md);
431 }
432 
434 {
435  /* type unsigned, no need to check < 0 */
436  if (type < NUM_GREASEPENCIL_MODIFIER_TYPES && type > 0 &&
437  modifier_gpencil_types[type]->name[0] != '\0') {
439  }
440 
441  return NULL;
442 }
443 
445 {
447 
448  strcpy(r_idname, GPENCIL_MODIFIER_TYPE_PANEL_PREFIX);
449  strcat(r_idname, mti->name);
450 }
451 
453 {
455 }
456 
458  GpencilModifierData *md_dst)
459 {
461 
462  /* md_dst may have already be fully initialized with some extra allocated data,
463  * we need to free it now to avoid memleak. */
464  if (mti->freeData) {
465  mti->freeData(md_dst);
466  }
467 
468  const size_t data_size = sizeof(GpencilModifierData);
469  const char *md_src_data = ((const char *)md_src) + data_size;
470  char *md_dst_data = ((char *)md_dst) + data_size;
471  BLI_assert(data_size <= (size_t)mti->struct_size);
472  memcpy(md_dst_data, md_src_data, (size_t)mti->struct_size - data_size);
473 }
474 
475 static void gpencil_modifier_copy_data_id_us_cb(void *UNUSED(userData),
476  Object *UNUSED(ob),
477  ID **idpoin,
478  int cb_flag)
479 {
480  ID *id = *idpoin;
481  if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
482  id_us_plus(id);
483  }
484 }
485 
487  GpencilModifierData *target,
488  const int flag)
489 {
491 
492  target->mode = md->mode;
493  target->flag = md->flag;
494  target->ui_expand_flag = md->ui_expand_flag; /* Expand the parent panel by default. */
495 
496  if (mti->copyData) {
497  mti->copyData(md, target);
498  }
499 
500  if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
501  if (mti->foreachIDLink) {
503  }
504  }
505 }
506 
508 {
509  BKE_gpencil_modifier_copydata_ex(md, target, 0);
510 }
511 
513 {
515 
516  for (; md; md = md->next) {
517  if (md->type == type) {
518  break;
519  }
520  }
521 
522  return md;
523 }
524 
526 {
527  char buffer[512];
528  va_list ap;
529  const char *format_tip = TIP_(format);
530 
531  va_start(ap, format);
532  vsnprintf(buffer, sizeof(buffer), format_tip, ap);
533  va_end(ap);
534  buffer[sizeof(buffer) - 1] = '\0';
535 
536  if (md->error) {
537  MEM_freeN(md->error);
538  }
539 
540  md->error = BLI_strdup(buffer);
541 
542  CLOG_STR_ERROR(&LOG, md->error);
543 }
544 
546  const GpencilModifierData *gmd)
547 {
548  return (ID_IS_OVERRIDE_LIBRARY(ob) &&
549  (gmd == NULL || (gmd->flag & eGpencilModifierFlag_OverrideLibrary_Local) == 0));
550 }
551 
553 {
555 
556  for (; md; md = md->next) {
558 
559  if (mti->foreachIDLink) {
560  mti->foreachIDLink(md, ob, walk, userData);
561  }
562  }
563 }
564 
567  void *userData)
568 {
570 
571  for (; md; md = md->next) {
573 
574  if (mti->foreachTexLink) {
575  mti->foreachTexLink(md, ob, walk, userData);
576  }
577  }
578 }
579 
581 {
582  return BLI_findstring(&(ob->greasepencil_modifiers), name, offsetof(GpencilModifierData, name));
583 }
584 
594 {
595  const bool is_render = (bool)(DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
596  const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
597  int cfra_eval = (int)DEG_get_ctime(depsgraph);
598 
599  int remap_cfra = cfra_eval;
600  if (time_remap) {
601  remap_cfra = BKE_gpencil_time_modifier_cfra(depsgraph, scene, ob, gpl, cfra_eval, is_render);
602  }
603 
604  return remap_cfra;
605 }
606 
608  Scene *scene,
609  Object *ob,
610  bGPDlayer *gpl)
611 {
612  int remap_cfra = gpencil_remap_time_get(depsgraph, scene, ob, gpl);
614 
615  return gpf;
616 }
617 
618 static void gpencil_assign_object_eval(Object *object)
619 {
621 
622  bGPdata *gpd_eval = object->runtime.gpd_eval;
623 
625 
626  if (object->id.tag & LIB_TAG_COPIED_ON_WRITE) {
627  object->data = gpd_eval;
628  }
629 }
630 
632 {
633  /* Create a temporary copy gpd. */
634  ID *newid = NULL;
636  bGPdata *gpd_eval = (bGPdata *)newid;
637  BLI_listbase_clear(&gpd_eval->layers);
638 
639  if (gpd->mat != NULL) {
640  gpd_eval->mat = MEM_dupallocN(gpd->mat);
641  }
642 
644 
645  /* Duplicate structure: layers and frames without strokes. */
646  LISTBASE_FOREACH (bGPDlayer *, gpl_orig, &gpd->layers) {
647  bGPDlayer *gpl_eval = BKE_gpencil_layer_duplicate(gpl_orig, true, false);
648  BLI_addtail(&gpd_eval->layers, gpl_eval);
649  gpl_eval->runtime.gpl_orig = gpl_orig;
650  /* Update frames orig pointers (helps for faster lookup in copy_frame_to_eval_cb). */
651  BKE_gpencil_layer_original_pointers_update(gpl_orig, gpl_eval);
652  }
653 
654  return gpd_eval;
655 }
656 
657 static void copy_frame_to_eval_ex(bGPDframe *gpf_orig, bGPDframe *gpf_eval)
658 {
659  /* Free any existing eval stroke data. This happens in case we have a single user on the data
660  * block and the strokes have not been deleted. */
661  if (!BLI_listbase_is_empty(&gpf_eval->strokes)) {
662  BKE_gpencil_free_strokes(gpf_eval);
663  }
664  /* Copy strokes to eval frame and update internal orig pointers. */
665  BKE_gpencil_frame_copy_strokes(gpf_orig, gpf_eval);
666  BKE_gpencil_frame_original_pointers_update(gpf_orig, gpf_eval);
667 }
668 
670  bGPDframe *gpf,
671  bGPDstroke *UNUSED(gps),
672  void *UNUSED(thunk))
673 {
674  /* Early return when callback:
675  * - Is not provided with a frame.
676  * - When the frame is the layer's active frame (already handled in
677  * gpencil_copy_visible_frames_to_eval).
678  */
679  if (gpf == NULL || gpf == gpl->actframe) {
680  return;
681  }
682 
684 }
685 
687 {
688  /* Remap layers active frame with time modifiers applied. */
689  bGPdata *gpd_eval = ob->data;
690  LISTBASE_FOREACH (bGPDlayer *, gpl_eval, &gpd_eval->layers) {
691  bGPDframe *gpf_eval = gpl_eval->actframe;
692  int remap_cfra = gpencil_remap_time_get(depsgraph, scene, ob, gpl_eval);
693  if (gpf_eval == NULL || gpf_eval->framenum != remap_cfra) {
694  gpl_eval->actframe = BKE_gpencil_layer_frame_get(gpl_eval, remap_cfra, GP_GETFRAME_USE_PREV);
695  }
696  /* Always copy active frame to eval, because the modifiers always evaluate the active frame,
697  * even if it's not visible (e.g. the layer is hidden).*/
698  if (gpl_eval->actframe != NULL) {
699  copy_frame_to_eval_ex(gpl_eval->actframe->runtime.gpf_orig, gpl_eval->actframe);
700  }
701  }
702 
703  /* Copy visible frames that are not the active one to evaluated version. */
705  NULL, ob, copy_frame_to_eval_cb, NULL, NULL, true, scene->r.cfra);
706 }
707 
709 {
710  bGPdata *gpd_eval = (bGPdata *)ob->data;
711  Object *ob_orig = (Object *)DEG_get_original_id(&ob->id);
712  bGPdata *gpd_orig = (bGPdata *)ob_orig->data;
713 
714  /* Need check if some layer is parented or transformed. */
715  bool do_parent = false;
716  bool do_transform = false;
717  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_orig->layers) {
718  if (gpl->parent != NULL) {
719  do_parent = true;
720  break;
721  }
722 
723  /* Only do layer transformations for non-zero or animated transforms. */
724  bool transformed = ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) ||
725  (!is_one_v3(gpl->scale)));
726  float tmp_mat[4][4];
727  loc_eul_size_to_mat4(tmp_mat, gpl->location, gpl->rotation, gpl->scale);
728  transformed |= !equals_m4m4(gpl->layer_mat, tmp_mat);
729  if (transformed) {
730  do_transform = true;
731  break;
732  }
733  }
734 
735  DEG_debug_print_eval(depsgraph, __func__, gpd_eval->id.name, gpd_eval);
736 
737  /* Delete any previously created runtime copy. */
738  if (ob->runtime.gpd_eval != NULL) {
739  /* Make sure to clear the pointer in case the runtime eval data points to the same data block.
740  * This can happen when the gpencil data block was not tagged for a depsgraph update after last
741  * call to this function (e.g. a frame change). */
742  if (gpd_eval == ob->runtime.gpd_eval) {
743  gpd_eval = NULL;
744  }
746  ob->runtime.gpd_eval = NULL;
747  ob->data = gpd_eval;
748  }
749 
750  const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd_orig);
751  const bool is_curve_edit = (bool)GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd_orig);
752  const bool do_modifiers = (bool)((!is_multiedit) && (!is_curve_edit) &&
753  (ob_orig->greasepencil_modifiers.first != NULL) &&
755  if ((!do_modifiers) && (!do_parent) && (!do_transform)) {
756  BLI_assert(ob->data != NULL);
757  return;
758  }
759 
760  /* If datablock has only one user, we can update its eval data directly.
761  * Otherwise, we need to have distinct copies for each instance, since applied transformations
762  * may differ. */
763  if (gpd_orig->id.us > 1) {
764  /* Copy of the original datablock's structure (layers and empty frames). */
766  /* Overwrite ob->data with gpd_eval here. */
768  }
769 
770  BLI_assert(ob->data != NULL);
771  /* Only copy strokes from visible frames to evaluated data. */
773 }
774 
776 {
777  bGPdata *gpd = (bGPdata *)ob->data;
778  const bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd);
779  const bool is_render = (bool)(DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
780  const bool is_curve_edit = (bool)(GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd) && !is_render);
781  const bool is_multiedit = (bool)(GPENCIL_MULTIEDIT_SESSIONS_ON(gpd) && !is_render);
782  const bool do_modifiers = (bool)((!is_multiedit) && (!is_curve_edit) &&
783  (ob->greasepencil_modifiers.first != NULL) &&
785  if (!do_modifiers) {
786  return;
787  }
788 
789  /* Init general modifiers data. */
791 
792  const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
793  bool is_first_lineart = true;
795 
797 
798  if (GPENCIL_MODIFIER_ACTIVE(md, is_render)) {
800 
801  if (GPENCIL_MODIFIER_EDIT(md, is_edit) && (!is_render)) {
802  continue;
803  }
804 
805  if (md->type == eGpencilModifierType_Lineart) {
806  BKE_gpencil_set_lineart_modifier_limits(md, &info, is_first_lineart);
807  is_first_lineart = false;
808  }
809 
810  /* Apply geometry modifiers (add new geometry). */
811  if (mti && mti->generateStrokes) {
812  mti->generateStrokes(md, depsgraph, ob);
813  }
814 
815  /* Apply deform modifiers and Time remap (only change geometry). */
816  if ((time_remap) || (mti && mti->deformStroke)) {
817  LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
819  if (gpf == NULL) {
820  continue;
821  }
822 
823  if (mti->deformStroke) {
824  LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
825  mti->deformStroke(md, depsgraph, ob, gpl, gpf, gps);
826  }
827  }
828  }
829  }
830  }
831  }
832 
833  /* Clear any cache data. */
835 
837 }
838 
840 {
841  if (modbase == NULL) {
842  return;
843  }
844 
845  LISTBASE_FOREACH (GpencilModifierData *, md, modbase) {
847  if (mti == NULL) {
848  return;
849  }
850 
851  BLO_write_struct_by_name(writer, mti->struct_name, md);
852 
853  if (md->type == eGpencilModifierType_Thick) {
855 
856  if (gpmd->curve_thickness) {
858  }
859  }
860  else if (md->type == eGpencilModifierType_Noise) {
862 
863  if (gpmd->curve_intensity) {
865  }
866  }
867  else if (md->type == eGpencilModifierType_Hook) {
869 
870  if (gpmd->curfalloff) {
872  }
873  }
874  else if (md->type == eGpencilModifierType_Tint) {
876  if (gpmd->colorband) {
877  BLO_write_struct(writer, ColorBand, gpmd->colorband);
878  }
879  if (gpmd->curve_intensity) {
881  }
882  }
883  else if (md->type == eGpencilModifierType_Smooth) {
885  if (gpmd->curve_intensity) {
887  }
888  }
889  else if (md->type == eGpencilModifierType_Color) {
891  if (gpmd->curve_intensity) {
893  }
894  }
895  else if (md->type == eGpencilModifierType_Opacity) {
897  if (gpmd->curve_intensity) {
899  }
900  }
901  else if (md->type == eGpencilModifierType_Dash) {
904  writer, DashGpencilModifierSegment, gpmd->segments_len, gpmd->segments);
905  }
906  }
907 }
908 
910 {
911  BLO_read_list(reader, lb);
912 
914  md->error = NULL;
915 
916  /* if modifiers disappear, or for upward compatibility */
917  if (NULL == BKE_gpencil_modifier_get_info(md->type)) {
918  md->type = eModifierType_None;
919  }
920 
921  if (md->type == eGpencilModifierType_Lattice) {
923  gpmd->cache_data = NULL;
924  }
925  else if (md->type == eGpencilModifierType_Hook) {
927 
928  BLO_read_data_address(reader, &hmd->curfalloff);
929  if (hmd->curfalloff) {
932  }
933  }
934  else if (md->type == eGpencilModifierType_Noise) {
936 
937  BLO_read_data_address(reader, &gpmd->curve_intensity);
938  if (gpmd->curve_intensity) {
940  /* initialize the curve. Maybe this could be moved to modififer logic */
942  }
943  }
944  else if (md->type == eGpencilModifierType_Thick) {
946 
947  BLO_read_data_address(reader, &gpmd->curve_thickness);
948  if (gpmd->curve_thickness) {
951  }
952  }
953  else if (md->type == eGpencilModifierType_Tint) {
955  BLO_read_data_address(reader, &gpmd->colorband);
956  BLO_read_data_address(reader, &gpmd->curve_intensity);
957  if (gpmd->curve_intensity) {
960  }
961  }
962  else if (md->type == eGpencilModifierType_Smooth) {
964  BLO_read_data_address(reader, &gpmd->curve_intensity);
965  if (gpmd->curve_intensity) {
968  }
969  }
970  else if (md->type == eGpencilModifierType_Color) {
972  BLO_read_data_address(reader, &gpmd->curve_intensity);
973  if (gpmd->curve_intensity) {
976  }
977  }
978  else if (md->type == eGpencilModifierType_Opacity) {
980  BLO_read_data_address(reader, &gpmd->curve_intensity);
981  if (gpmd->curve_intensity) {
984  }
985  }
986  else if (md->type == eGpencilModifierType_Dash) {
988  BLO_read_data_address(reader, &gpmd->segments);
989  for (int i = 0; i < gpmd->segments_len; i++) {
990  gpmd->segments[i].dmd = gpmd;
991  }
992  }
993  if (md->type == eGpencilModifierType_Shrinkwrap) {
995  gpmd->cache_data = NULL;
996  }
997  }
998 }
999 
1001 {
1003 
1004  /* If linking from a library, clear 'local' library override flag. */
1005  if (ID_IS_LINKED(ob)) {
1008  }
1009  }
1010 }
void BKE_curvemapping_init(struct CurveMapping *cumap)
Definition: colortools.c:1235
void BKE_curvemapping_blend_read(struct BlendDataReader *reader, struct CurveMapping *cumap)
Definition: colortools.c:1300
void BKE_curvemapping_blend_write(struct BlendWriter *writer, const struct CurveMapping *cumap)
support for deformation groups and hooks.
void BKE_defgroup_copy_list(struct ListBase *outbase, const struct ListBase *inbase)
void BKE_gpencil_eval_delete(struct bGPdata *gpd_eval)
Definition: gpencil.c:498
bool BKE_gpencil_free_strokes(struct bGPDframe *gpf)
Definition: gpencil.c:414
struct bGPDlayer * BKE_gpencil_layer_duplicate(const struct bGPDlayer *gpl_src, bool dup_frames, bool dup_strokes)
void BKE_gpencil_layer_original_pointers_update(const struct bGPDlayer *gpl_orig, const struct bGPDlayer *gpl_eval)
Definition: gpencil.c:2663
void BKE_gpencil_visible_stroke_advanced_iter(struct ViewLayer *view_layer, struct Object *ob, gpIterCb layer_cb, gpIterCb stroke_cb, void *thunk, bool do_onion, int cfra)
Definition: gpencil.c:2430
void BKE_gpencil_frame_original_pointers_update(const struct bGPDframe *gpf_orig, const struct bGPDframe *gpf_eval)
Definition: gpencil.c:2630
struct bGPDframe * BKE_gpencil_layer_frame_get(struct bGPDlayer *gpl, int cframe, eGP_GetFrame_Mode addnew)
Definition: gpencil.c:1232
void BKE_gpencil_frame_copy_strokes(struct bGPDframe *gpf_src, struct bGPDframe *gpf_dst)
Definition: gpencil.c:920
#define GPENCIL_SIMPLIFY_MODIF(scene)
Definition: BKE_gpencil.h:45
@ GP_GETFRAME_USE_PREV
Definition: BKE_gpencil.h:338
#define GPENCIL_MODIFIER_EDIT(_md, _is_edit)
#define GPENCIL_MODIFIER_TYPE_PANEL_PREFIX
void(* GreasePencilTexWalkFunc)(void *userData, struct Object *ob, struct GpencilModifierData *md, const char *propname)
@ eGpencilModifierTypeFlag_EnableInEditmode
#define GPENCIL_MODIFIER_ACTIVE(_md, _is_render)
void(* GreasePencilIDWalkFunc)(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
void BKE_lattice_deform_data_destroy(struct LatticeDeformData *lattice_deform_data)
struct LatticeDeformData * BKE_lattice_deform_data_create(const struct Object *oblatt, const struct Object *ob) ATTR_WARN_UNUSED_RESULT
void BKE_libblock_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, int orig_flag)
@ LIB_ID_COPY_LOCALIZE
Definition: BKE_lib_id.h:187
@ LIB_ID_CREATE_NO_USER_REFCOUNT
Definition: BKE_lib_id.h:126
void id_us_min(struct ID *id)
Definition: lib_id.c:313
void id_us_plus(struct ID *id)
Definition: lib_id.c:305
@ IDWALK_CB_USER
Definition: BKE_lib_query.h:73
General operations, lookup, etc. for materials.
struct Mesh * BKE_modifier_get_evaluated_mesh_from_evaluated_object(struct Object *ob_eval)
General operations, lookup, etc. for blender objects.
void BKE_object_modifiers_lib_link_common(void *userData, struct Object *ob, struct ID **idpoin, int cb_flag)
Definition: object.cc:5562
bool BKE_shrinkwrap_init_tree(struct ShrinkwrapTreeData *data, Mesh *mesh, int shrinkType, int shrinkMode, bool force_normals)
Definition: shrinkwrap.c:97
void BKE_shrinkwrap_free_tree(struct ShrinkwrapTreeData *data)
Definition: shrinkwrap.c:147
#define BLI_assert(a)
Definition: BLI_assert.h:46
BLI_INLINE bool BLI_listbase_is_empty(const struct ListBase *lb)
Definition: BLI_listbase.h:269
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:336
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:273
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:80
void * BLI_findstring(const struct ListBase *listbase, const char *id, int offset) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
bool equals_m4m4(const float mat1[4][4], const float mat2[4][4])
Definition: math_matrix.c:2531
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 bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
MINLINE bool is_one_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:42
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 UNUSED(x)
#define MAX2(a, b)
#define ELEM(...)
#define MIN2(a, b)
#define BLO_read_data_address(reader, ptr_p)
void BLO_write_struct_by_name(BlendWriter *writer, const char *struct_name, const void *data_ptr)
Definition: writefile.c:1494
#define BLO_write_struct(writer, struct_name, data_ptr)
void BLO_read_list(BlendDataReader *reader, struct ListBase *list)
Definition: readfile.c:5172
#define BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
#define TIP_(msgid)
#define DATA_(msgid)
#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
@ DAG_EVAL_RENDER
Definition: DEG_depsgraph.h:46
void DEG_debug_print_eval(struct Depsgraph *depsgraph, const char *function_name, const char *object_name, const void *object_address)
float DEG_get_ctime(const Depsgraph *graph)
eEvaluationMode DEG_get_mode(const Depsgraph *graph)
struct ID * DEG_get_original_id(struct ID *id)
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
#define ID_IS_LINKED(_id)
Definition: DNA_ID.h:566
@ LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT
Definition: DNA_ID.h:730
@ LIB_TAG_COPIED_ON_WRITE
Definition: DNA_ID.h:720
#define ID_IS_OVERRIDE_LIBRARY(_id)
Definition: DNA_ID.h:588
@ eGpencilModifierMode_Render
@ eGpencilModifierMode_Editmode
@ eGpencilModifierMode_Virtual
@ eGpencilModifierMode_Realtime
struct GpencilModifierData GpencilModifierData
@ eGpencilModifierFlag_OverrideLibrary_Local
@ eGpencilModifierType_Dash
@ eGpencilModifierType_Noise
@ eGpencilModifierType_Color
@ eGpencilModifierType_Lattice
@ eGpencilModifierType_Opacity
@ eGpencilModifierType_Hook
@ eGpencilModifierType_Shrinkwrap
@ eGpencilModifierType_Armature
@ eGpencilModifierType_Lineart
@ eGpencilModifierType_Smooth
@ eGpencilModifierType_Tint
@ NUM_GREASEPENCIL_MODIFIER_TYPES
@ eGpencilModifierType_Thick
@ eGpencilModifierType_Offset
#define GPENCIL_MULTIEDIT_SESSIONS_ON(gpd)
#define GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd)
#define GPENCIL_ANY_EDIT_MODE(gpd)
@ eModifierType_None
Object is a sort of wrapper for general info.
@ OB_LATTICE
@ OB_ARMATURE
@ PARSKEL
@ UI_PANEL_DATA_EXPAND_ROOT
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[])
static VirtualModifierData virtualModifierCommonData
Scene scene
const Depsgraph * depsgraph
bool BKE_gpencil_has_geometry_modifiers(Object *ob)
bool BKE_gpencil_has_transform_modifiers(Object *ob)
void BKE_gpencil_modifier_panel_expand(GpencilModifierData *md)
void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
void BKE_gpencil_modifiers_foreach_ID_link(Object *ob, GreasePencilIDWalkFunc walk, void *userData)
GpencilModifierData * BKE_gpencil_modifiers_get_virtual_modifierlist(const Object *ob, GpencilVirtualModifierData *UNUSED(virtualModifierData))
GpencilModifierData * BKE_gpencil_modifiers_findby_type(Object *ob, GpencilModifierType type)
void BKE_gpencil_modifier_blend_write(BlendWriter *writer, ListBase *modbase)
static int gpencil_remap_time_get(Depsgraph *depsgraph, Scene *scene, Object *ob, bGPDlayer *gpl)
GpencilModifierData * BKE_gpencil_modifier_new(int type)
static void copy_frame_to_eval_cb(bGPDlayer *gpl, bGPDframe *gpf, bGPDstroke *UNUSED(gps), void *UNUSED(thunk))
void BKE_gpencil_frame_active_set(Depsgraph *depsgraph, bGPdata *gpd)
void BKE_gpencil_modifier_free_ex(GpencilModifierData *md, const int flag)
static bGPdata * gpencil_copy_structure_for_eval(bGPdata *gpd)
static void copy_frame_to_eval_ex(bGPDframe *gpf_orig, bGPDframe *gpf_eval)
void BKE_gpencil_modifierType_panel_id(GpencilModifierType type, char *r_idname)
void BKE_gpencil_modifier_blend_read_lib(BlendLibReader *reader, Object *ob)
static void modifier_free_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag)
void BKE_gpencil_modifier_init(void)
void BKE_gpencil_cache_data_init(Depsgraph *depsgraph, Object *ob)
static void gpencil_modifier_copy_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag)
bool BKE_gpencil_modifier_is_nonlocal_in_liboverride(const Object *ob, const GpencilModifierData *gmd)
int BKE_gpencil_time_modifier_cfra(Depsgraph *depsgraph, Scene *scene, Object *ob, bGPDlayer *gpl, const int cfra, const bool is_render)
bool BKE_gpencil_modifier_depends_ontime(GpencilModifierData *md)
void BKE_gpencil_modifier_set_error(GpencilModifierData *md, const char *format,...)
bool BKE_gpencil_modifier_unique_name(ListBase *modifiers, GpencilModifierData *gmd)
static GpencilModifierTypeInfo * modifier_gpencil_types[NUM_GREASEPENCIL_MODIFIER_TYPES]
void BKE_gpencil_cache_data_clear(Object *ob)
static void gpencil_copy_visible_frames_to_eval(Depsgraph *depsgraph, Scene *scene, Object *ob)
bGPDframe * BKE_gpencil_frame_retime_get(Depsgraph *depsgraph, Scene *scene, Object *ob, bGPDlayer *gpl)
void BKE_gpencil_modifiers_foreach_tex_link(Object *ob, GreasePencilTexWalkFunc walk, void *userData)
void BKE_gpencil_set_lineart_modifier_limits(GpencilModifierData *md, const GpencilLineartLimitInfo *info, const bool is_first_lineart)
void BKE_gpencil_modifier_blend_read_data(BlendDataReader *reader, ListBase *lb)
GpencilLineartLimitInfo BKE_gpencil_get_lineart_modifier_limits(const Object *ob)
bool BKE_gpencil_has_time_modifiers(Object *ob)
void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *ob)
GpencilModifierData * BKE_gpencil_modifiers_findby_name(Object *ob, const char *name)
void BKE_gpencil_modifier_copydata_ex(GpencilModifierData *md, GpencilModifierData *target, const int flag)
static CLG_LogRef LOG
void BKE_gpencil_modifier_copydata(GpencilModifierData *md, GpencilModifierData *target)
static void gpencil_assign_object_eval(Object *object)
void BKE_gpencil_modifier_free(GpencilModifierData *md)
const GpencilModifierTypeInfo * BKE_gpencil_modifier_get_info(GpencilModifierType type)
void BKE_gpencil_modifier_copydata_generic(const GpencilModifierData *md_src, GpencilModifierData *md_dst)
bool BKE_gpencil_is_first_lineart_in_stack(const Object *ob, const GpencilModifierData *md)
ccl_global float * buffer
void MOD_lineart_clear_cache(struct LineartCache **lc)
Definition: lineart_cpu.c:3539
format
Definition: logImageCore.h:38
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
struct CurveMapping * curve_intensity
DashGpencilModifierSegment * segments
struct DashGpencilModifierData * dmd
struct GpencilModifierData * next
void(* generateStrokes)(struct GpencilModifierData *md, struct Depsgraph *depsgraph, struct Object *ob)
GpencilModifierTypeFlag flags
void(* initData)(struct GpencilModifierData *md)
void(* copyData)(const struct GpencilModifierData *md, struct GpencilModifierData *target)
void(* freeData)(struct GpencilModifierData *md)
bool(* dependsOnTime)(struct GpencilModifierData *md)
void(* foreachIDLink)(struct GpencilModifierData *md, struct Object *ob, GreasePencilIDWalkFunc walk, void *userData)
void(* deformStroke)(struct GpencilModifierData *md, struct Depsgraph *depsgraph, struct Object *ob, struct bGPDlayer *gpl, struct bGPDframe *gpf, struct bGPDstroke *gps)
void(* foreachTexLink)(struct GpencilModifierData *md, struct Object *ob, GreasePencilTexWalkFunc walk, void *userData)
int(* remapTime)(struct GpencilModifierData *md, struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, struct bGPDlayer *gpl, int cfra)
Definition: DNA_ID.h:368
int tag
Definition: DNA_ID.h:387
int us
Definition: DNA_ID.h:388
char name[66]
Definition: DNA_ID.h:378
struct LatticeDeformData * cache_data
void * first
Definition: DNA_listBase.h:31
struct CurveMapping * curve_intensity
struct bGPdata * gpd_eval
short partype
ListBase greasepencil_modifiers
Object_Runtime runtime
struct Object * parent
void * data
struct RenderData r
struct ShrinkwrapTreeData * cache_data
struct CurveMapping * curve_thickness
struct CurveMapping * curve_intensity
ArmatureModifierData amd
Definition: BKE_modifier.h:535
LatticeModifierData lmd
Definition: BKE_modifier.h:537
struct bGPDframe * gpf_orig
bGPDframe_Runtime runtime
ListBase strokes
struct bGPDlayer * gpl_orig
struct Object * parent
bGPDframe * actframe
float layer_mat[4][4]
bGPDlayer_Runtime runtime
float rotation[3]
float scale[3]
float location[3]
struct LineartCache * lineart_cache
ListBase vertex_group_names
ListBase layers
struct Material ** mat
bGPdata_Runtime runtime
ccl_device_inline int mod(int x, int m)
Definition: util/math.h:490