1 /*
2 * This program is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU General Public License
4 * as published by the Free Software Foundation; either version 2
5 * of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * The Original Code is Copyright (C) 2017, Blender Foundation
17 * This is a new part of Blender
18 */
19
20 /** \file
21 * \ingroup bke
22 */
23
24 #include <stdio.h>
25
26 #include "MEM_guardedalloc.h"
27
28 #include "BLI_blenlib.h"
29 #include "BLI_math_geom.h"
30 #include "BLI_math_vector.h"
31 #include "BLI_string_utils.h"
32 #include "BLI_utildefines.h"
33
34 #include "BLT_translation.h"
35
36 #include "DNA_armature_types.h"
37 #include "DNA_gpencil_modifier_types.h"
38 #include "DNA_gpencil_types.h"
39 #include "DNA_meshdata_types.h"
40 #include "DNA_object_types.h"
41 #include "DNA_scene_types.h"
42
43 #include "BKE_gpencil.h"
44 #include "BKE_gpencil_geom.h"
45 #include "BKE_gpencil_modifier.h"
46 #include "BKE_lattice.h"
47 #include "BKE_lib_id.h"
48 #include "BKE_lib_query.h"
49 #include "BKE_material.h"
50 #include "BKE_object.h"
51
52 #include "DEG_depsgraph.h"
53 #include "DEG_depsgraph_query.h"
54
55 #include "MOD_gpencil_modifiertypes.h"
56
57 #include "CLG_log.h"
58
59 static CLG_LogRef LOG = {"bke.gpencil_modifier"};
60 static GpencilModifierTypeInfo *modifier_gpencil_types[NUM_GREASEPENCIL_MODIFIER_TYPES] = {NULL};
61 #if 0
62 /* Note that GPencil actually does not support these atm, but might do in the future. */
63 static GpencilVirtualModifierData virtualModifierCommonData;
64 #endif
65
66 /* Lattice Modifier ---------------------------------- */
67 /* Usually, evaluation of the lattice modifier is self-contained.
68 * However, since GP's modifiers operate on a per-stroke basis,
69 * we need to these two extra functions that called before/after
70 * each loop over all the geometry being evaluated.
71 */
72
73 /**
74 * Init grease pencil lattice deform data.
75 * \param ob: Grease pencil object
76 */
BKE_gpencil_lattice_init(Object * ob)77 void BKE_gpencil_lattice_init(Object *ob)
78 {
79 LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) {
80 if (md->type == eGpencilModifierType_Lattice) {
81 LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md;
82 Object *latob = NULL;
83
84 latob = mmd->object;
85 if ((!latob) || (latob->type != OB_LATTICE)) {
86 return;
87 }
88 if (mmd->cache_data) {
89 BKE_lattice_deform_data_destroy(mmd->cache_data);
90 }
91
92 /* init deform data */
93 mmd->cache_data = BKE_lattice_deform_data_create(latob, ob);
94 }
95 }
96 }
97
98 /**
99 * Clear grease pencil lattice deform data.
100 * \param ob: Grease pencil object
101 */
BKE_gpencil_lattice_clear(Object * ob)102 void BKE_gpencil_lattice_clear(Object *ob)
103 {
104 LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) {
105 if (md->type == eGpencilModifierType_Lattice) {
106 LatticeGpencilModifierData *mmd = (LatticeGpencilModifierData *)md;
107 if ((mmd) && (mmd->cache_data)) {
108 BKE_lattice_deform_data_destroy(mmd->cache_data);
109 mmd->cache_data = NULL;
110 }
111 }
112 }
113 }
114
115 /* *************************************************** */
116 /* Modifier Methods - Evaluation Loops, etc. */
117
118 /* This is to include things that are not modifiers in the evaluation of the modifier stack, for
119 * example parenting to an armature or lattice without having a real modifier. */
BKE_gpencil_modifiers_get_virtual_modifierlist(const Object * ob,GpencilVirtualModifierData * UNUSED (virtualModifierData))120 GpencilModifierData *BKE_gpencil_modifiers_get_virtual_modifierlist(
121 const Object *ob, GpencilVirtualModifierData *UNUSED(virtualModifierData))
122 {
123 GpencilModifierData *md = ob->greasepencil_modifiers.first;
124
125 #if 0
126 /* Note that GPencil actually does not support these atm, but might do in the future. */
127 *virtualModifierData = virtualModifierCommonData;
128 if (ob->parent) {
129 if (ob->parent->type == OB_ARMATURE && ob->partype == PARSKEL) {
130 virtualModifierData->amd.object = ob->parent;
131 virtualModifierData->amd.modifier.next = md;
132 virtualModifierData->amd.deformflag = ((bArmature *)(ob->parent->data))->deformflag;
133 md = &virtualModifierData->amd.modifier;
134 }
135 else if (ob->parent->type == OB_LATTICE && ob->partype == PARSKEL) {
136 virtualModifierData->lmd.object = ob->parent;
137 virtualModifierData->lmd.modifier.next = md;
138 md = &virtualModifierData->lmd.modifier;
139 }
140 }
141 #endif
142
143 return md;
144 }
145
146 /**
147 * Check if object has grease pencil Geometry modifiers.
148 * \param ob: Grease pencil object
149 * \return True if exist
150 */
BKE_gpencil_has_geometry_modifiers(Object * ob)151 bool BKE_gpencil_has_geometry_modifiers(Object *ob)
152 {
153 LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) {
154 const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
155
156 if (mti && mti->generateStrokes) {
157 return true;
158 }
159 }
160 return false;
161 }
162
163 /**
164 * Check if object has grease pencil Time modifiers.
165 * \param ob: Grease pencil object
166 * \return True if exist
167 */
BKE_gpencil_has_time_modifiers(Object * ob)168 bool BKE_gpencil_has_time_modifiers(Object *ob)
169 {
170 LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) {
171 const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
172
173 if (mti && mti->remapTime) {
174 return true;
175 }
176 }
177 return false;
178 }
179
180 /**
181 * Check if object has grease pencil transform stroke modifiers.
182 * \param ob: Grease pencil object
183 * \return True if exist
184 */
BKE_gpencil_has_transform_modifiers(Object * ob)185 bool BKE_gpencil_has_transform_modifiers(Object *ob)
186 {
187 LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) {
188 /* Only if enabled in edit mode. */
189 if (!GPENCIL_MODIFIER_EDIT(md, true) && GPENCIL_MODIFIER_ACTIVE(md, false)) {
190 if ((md->type == eGpencilModifierType_Armature) || (md->type == eGpencilModifierType_Hook) ||
191 (md->type == eGpencilModifierType_Lattice) ||
192 (md->type == eGpencilModifierType_Offset)) {
193 return true;
194 }
195 }
196 }
197 return false;
198 }
199
200 /* apply time modifiers */
gpencil_time_modifier(Depsgraph * depsgraph,Scene * scene,Object * ob,bGPDlayer * gpl,int cfra,bool is_render)201 static int gpencil_time_modifier(
202 Depsgraph *depsgraph, Scene *scene, Object *ob, bGPDlayer *gpl, int cfra, bool is_render)
203 {
204 bGPdata *gpd = ob->data;
205 const bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd);
206 int nfra = cfra;
207
208 LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) {
209 if (GPENCIL_MODIFIER_ACTIVE(md, is_render)) {
210 const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
211
212 if ((GPENCIL_MODIFIER_EDIT(md, is_edit)) && (!is_render)) {
213 continue;
214 }
215
216 if (mti->remapTime) {
217 nfra = mti->remapTime(md, depsgraph, scene, ob, gpl, cfra);
218 /* if the frame number changed, don't evaluate more and return */
219 if (nfra != cfra) {
220 return nfra;
221 }
222 }
223 }
224 }
225
226 /* if no time modifier, return original frame number */
227 return nfra;
228 }
229
230 /**
231 * Set current grease pencil active frame.
232 * \param depsgraph: Current depsgraph
233 * \param gpd: Grease pencil data-block.
234 */
BKE_gpencil_frame_active_set(Depsgraph * depsgraph,bGPdata * gpd)235 void BKE_gpencil_frame_active_set(Depsgraph *depsgraph, bGPdata *gpd)
236 {
237 DEG_debug_print_eval(depsgraph, __func__, gpd->id.name, gpd);
238 int ctime = (int)DEG_get_ctime(depsgraph);
239
240 /* update active frame */
241 LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
242 gpl->actframe = BKE_gpencil_layer_frame_get(gpl, ctime, GP_GETFRAME_USE_PREV);
243 }
244
245 if (DEG_is_active(depsgraph)) {
246 bGPdata *gpd_orig = (bGPdata *)DEG_get_original_id(&gpd->id);
247
248 /* sync "actframe" changes back to main-db too,
249 * so that editing tools work with copy-on-write
250 * when the current frame changes
251 */
252 LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_orig->layers) {
253 gpl->actframe = BKE_gpencil_layer_frame_get(gpl, ctime, GP_GETFRAME_USE_PREV);
254 }
255 }
256 }
257
258 /**
259 * Initialize grease pencil modifier.
260 */
BKE_gpencil_modifier_init(void)261 void BKE_gpencil_modifier_init(void)
262 {
263 /* Initialize modifier types */
264 gpencil_modifier_type_init(modifier_gpencil_types); /* MOD_gpencil_util.c */
265
266 #if 0
267 /* Note that GPencil actually does not support these atm, but might do in the future. */
268 /* Initialize global cmmon storage used for virtual modifier list */
269 GpencilModifierData *md;
270 md = BKE_gpencil_modifier_new(eGpencilModifierType_Armature);
271 virtualModifierCommonData.amd = *((ArmatureGpencilModifierData *)md);
272 BKE_gpencil_modifier_free(md);
273
274 md = BKE_gpencil_modifier_new(eGpencilModifierType_Lattice);
275 virtualModifierCommonData.lmd = *((LatticeGpencilModifierData *)md);
276 BKE_gpencil_modifier_free(md);
277
278 virtualModifierCommonData.amd.modifier.mode |= eGpencilModifierMode_Virtual;
279 virtualModifierCommonData.lmd.modifier.mode |= eGpencilModifierMode_Virtual;
280 #endif
281 }
282
283 /**
284 * Create new grease pencil modifier.
285 * \param type: Type of modifier
286 * \return New modifier pointer
287 */
BKE_gpencil_modifier_new(int type)288 GpencilModifierData *BKE_gpencil_modifier_new(int type)
289 {
290 const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(type);
291 GpencilModifierData *md = MEM_callocN(mti->struct_size, mti->struct_name);
292
293 /* note, this name must be made unique later */
294 BLI_strncpy(md->name, DATA_(mti->name), sizeof(md->name));
295
296 md->type = type;
297 md->mode = eGpencilModifierMode_Realtime | eGpencilModifierMode_Render;
298 md->flag = eGpencilModifierFlag_OverrideLibrary_Local;
299 md->ui_expand_flag = 1; /* Only expand the parent panel at first. */
300
301 if (mti->flags & eGpencilModifierTypeFlag_EnableInEditmode) {
302 md->mode |= eGpencilModifierMode_Editmode;
303 }
304
305 if (mti->initData) {
306 mti->initData(md);
307 }
308
309 return md;
310 }
311
modifier_free_data_id_us_cb(void * UNUSED (userData),Object * UNUSED (ob),ID ** idpoin,int cb_flag)312 static void modifier_free_data_id_us_cb(void *UNUSED(userData),
313 Object *UNUSED(ob),
314 ID **idpoin,
315 int cb_flag)
316 {
317 ID *id = *idpoin;
318 if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
319 id_us_min(id);
320 }
321 }
322
323 /**
324 * Free grease pencil modifier data
325 * \param md: Modifier data
326 * \param flag: Flags
327 */
BKE_gpencil_modifier_free_ex(GpencilModifierData * md,const int flag)328 void BKE_gpencil_modifier_free_ex(GpencilModifierData *md, const int flag)
329 {
330 const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
331
332 if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
333 if (mti->foreachIDLink) {
334 mti->foreachIDLink(md, NULL, modifier_free_data_id_us_cb, NULL);
335 }
336 }
337
338 if (mti->freeData) {
339 mti->freeData(md);
340 }
341 if (md->error) {
342 MEM_freeN(md->error);
343 }
344
345 MEM_freeN(md);
346 }
347
348 /**
349 * Free grease pencil modifier data
350 * \param md: Modifier data
351 */
BKE_gpencil_modifier_free(GpencilModifierData * md)352 void BKE_gpencil_modifier_free(GpencilModifierData *md)
353 {
354 BKE_gpencil_modifier_free_ex(md, 0);
355 }
356
357 /* check unique name */
BKE_gpencil_modifier_unique_name(ListBase * modifiers,GpencilModifierData * gmd)358 bool BKE_gpencil_modifier_unique_name(ListBase *modifiers, GpencilModifierData *gmd)
359 {
360 if (modifiers && gmd) {
361 const GpencilModifierTypeInfo *gmti = BKE_gpencil_modifier_get_info(gmd->type);
362 return BLI_uniquename(modifiers,
363 gmd,
364 DATA_(gmti->name),
365 '.',
366 offsetof(GpencilModifierData, name),
367 sizeof(gmd->name));
368 }
369 return false;
370 }
371
372 /**
373 * Check if grease pencil modifier depends on time.
374 * \param md: Modifier data
375 * \return True if depends on time
376 */
BKE_gpencil_modifier_depends_ontime(GpencilModifierData * md)377 bool BKE_gpencil_modifier_depends_ontime(GpencilModifierData *md)
378 {
379 const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
380
381 return mti->dependsOnTime && mti->dependsOnTime(md);
382 }
383
384 /**
385 * Get grease pencil modifier information.
386 * \param type: Type of modifier
387 * \return Pointer to type
388 */
BKE_gpencil_modifier_get_info(GpencilModifierType type)389 const GpencilModifierTypeInfo *BKE_gpencil_modifier_get_info(GpencilModifierType type)
390 {
391 /* type unsigned, no need to check < 0 */
392 if (type < NUM_GREASEPENCIL_MODIFIER_TYPES && type > 0 &&
393 modifier_gpencil_types[type]->name[0] != '\0') {
394 return modifier_gpencil_types[type];
395 }
396
397 return NULL;
398 }
399
400 /**
401 * Get the idname of the modifier type's panel, which was defined in the #panelRegister callback.
402 *
403 * \param type: Type of modifier
404 * \param r_idname: ID name
405 */
BKE_gpencil_modifierType_panel_id(GpencilModifierType type,char * r_idname)406 void BKE_gpencil_modifierType_panel_id(GpencilModifierType type, char *r_idname)
407 {
408 const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(type);
409
410 strcpy(r_idname, GPENCIL_MODIFIER_TYPE_PANEL_PREFIX);
411 strcat(r_idname, mti->name);
412 }
413
414 /**
415 * Generic grease pencil modifier copy data.
416 * \param md_src: Source modifier data
417 * \param md_dst: Target modifier data
418 */
BKE_gpencil_modifier_copydata_generic(const GpencilModifierData * md_src,GpencilModifierData * md_dst)419 void BKE_gpencil_modifier_copydata_generic(const GpencilModifierData *md_src,
420 GpencilModifierData *md_dst)
421 {
422 const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md_src->type);
423
424 /* md_dst may have already be fully initialized with some extra allocated data,
425 * we need to free it now to avoid memleak. */
426 if (mti->freeData) {
427 mti->freeData(md_dst);
428 }
429
430 const size_t data_size = sizeof(GpencilModifierData);
431 const char *md_src_data = ((const char *)md_src) + data_size;
432 char *md_dst_data = ((char *)md_dst) + data_size;
433 BLI_assert(data_size <= (size_t)mti->struct_size);
434 memcpy(md_dst_data, md_src_data, (size_t)mti->struct_size - data_size);
435 }
436
gpencil_modifier_copy_data_id_us_cb(void * UNUSED (userData),Object * UNUSED (ob),ID ** idpoin,int cb_flag)437 static void gpencil_modifier_copy_data_id_us_cb(void *UNUSED(userData),
438 Object *UNUSED(ob),
439 ID **idpoin,
440 int cb_flag)
441 {
442 ID *id = *idpoin;
443 if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
444 id_us_plus(id);
445 }
446 }
447
448 /**
449 * Copy grease pencil modifier data.
450 * \param md: Source modifier data
451 * \param target: Target modifier data
452 * \parm flag: Flags
453 */
BKE_gpencil_modifier_copydata_ex(GpencilModifierData * md,GpencilModifierData * target,const int flag)454 void BKE_gpencil_modifier_copydata_ex(GpencilModifierData *md,
455 GpencilModifierData *target,
456 const int flag)
457 {
458 const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
459
460 target->mode = md->mode;
461 target->flag = md->flag;
462 target->ui_expand_flag = md->ui_expand_flag; /* Expand the parent panel by default. */
463
464 if (mti->copyData) {
465 mti->copyData(md, target);
466 }
467
468 if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
469 if (mti->foreachIDLink) {
470 mti->foreachIDLink(target, NULL, gpencil_modifier_copy_data_id_us_cb, NULL);
471 }
472 }
473 }
474
475 /**
476 * Copy grease pencil modifier data.
477 * \param md: Source modifier data
478 * \param target: Target modifier data
479 */
BKE_gpencil_modifier_copydata(GpencilModifierData * md,GpencilModifierData * target)480 void BKE_gpencil_modifier_copydata(GpencilModifierData *md, GpencilModifierData *target)
481 {
482 BKE_gpencil_modifier_copydata_ex(md, target, 0);
483 }
484
BKE_gpencil_modifiers_findby_type(Object * ob,GpencilModifierType type)485 GpencilModifierData *BKE_gpencil_modifiers_findby_type(Object *ob, GpencilModifierType type)
486 {
487 GpencilModifierData *md = ob->greasepencil_modifiers.first;
488
489 for (; md; md = md->next) {
490 if (md->type == type) {
491 break;
492 }
493 }
494
495 return md;
496 }
497
498 /**
499 * Set grease pencil modifier error.
500 * \param md: Modifier data
501 * \param _format: Format
502 */
BKE_gpencil_modifier_set_error(GpencilModifierData * md,const char * _format,...)503 void BKE_gpencil_modifier_set_error(GpencilModifierData *md, const char *_format, ...)
504 {
505 char buffer[512];
506 va_list ap;
507 const char *format = TIP_(_format);
508
509 va_start(ap, _format);
510 vsnprintf(buffer, sizeof(buffer), format, ap);
511 va_end(ap);
512 buffer[sizeof(buffer) - 1] = '\0';
513
514 if (md->error) {
515 MEM_freeN(md->error);
516 }
517
518 md->error = BLI_strdup(buffer);
519
520 CLOG_STR_ERROR(&LOG, md->error);
521 }
522
523 /**
524 * Link grease pencil modifier related IDs.
525 * \param ob: Grease pencil object
526 * \param walk: Walk option
527 * \param userData: User data
528 */
BKE_gpencil_modifiers_foreach_ID_link(Object * ob,GreasePencilIDWalkFunc walk,void * userData)529 void BKE_gpencil_modifiers_foreach_ID_link(Object *ob, GreasePencilIDWalkFunc walk, void *userData)
530 {
531 GpencilModifierData *md = ob->greasepencil_modifiers.first;
532
533 for (; md; md = md->next) {
534 const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
535
536 if (mti->foreachIDLink) {
537 mti->foreachIDLink(md, ob, walk, userData);
538 }
539 }
540 }
541
542 /**
543 * Link grease pencil modifier related Texts.
544 * \param ob: Grease pencil object
545 * \param walk: Walk option
546 * \param userData: User data
547 */
BKE_gpencil_modifiers_foreach_tex_link(Object * ob,GreasePencilTexWalkFunc walk,void * userData)548 void BKE_gpencil_modifiers_foreach_tex_link(Object *ob,
549 GreasePencilTexWalkFunc walk,
550 void *userData)
551 {
552 GpencilModifierData *md = ob->greasepencil_modifiers.first;
553
554 for (; md; md = md->next) {
555 const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
556
557 if (mti->foreachTexLink) {
558 mti->foreachTexLink(md, ob, walk, userData);
559 }
560 }
561 }
562
563 /**
564 * Find grease pencil modifier by name.
565 * \param ob: Grease pencil object
566 * \param name: Name to find
567 * \return Pointer to modifier
568 */
BKE_gpencil_modifiers_findby_name(Object * ob,const char * name)569 GpencilModifierData *BKE_gpencil_modifiers_findby_name(Object *ob, const char *name)
570 {
571 return BLI_findstring(&(ob->greasepencil_modifiers), name, offsetof(GpencilModifierData, name));
572 }
573
574 /**
575 * Remap grease pencil frame (Time modifier)
576 * \param depsgraph: Current depsgraph
577 * \param scene: Current scene
578 * \param ob: Grease pencil object
579 * \param gpl: Grease pencil layer
580 * \return New frame number
581 */
gpencil_remap_time_get(Depsgraph * depsgraph,Scene * scene,Object * ob,bGPDlayer * gpl)582 static int gpencil_remap_time_get(Depsgraph *depsgraph, Scene *scene, Object *ob, bGPDlayer *gpl)
583 {
584 const bool is_render = (bool)(DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
585 const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
586 int cfra_eval = (int)DEG_get_ctime(depsgraph);
587
588 int remap_cfra = cfra_eval;
589 if (time_remap) {
590 remap_cfra = gpencil_time_modifier(depsgraph, scene, ob, gpl, cfra_eval, is_render);
591 }
592
593 return remap_cfra;
594 }
595
596 /** Get the current frame re-timed with time modifiers.
597 * \param depsgraph: Current depsgraph.
598 * \param scene: Current scene
599 * \param ob: Grease pencil object
600 * \param gpl: Grease pencil layer
601 * \return New frame number
602 */
BKE_gpencil_frame_retime_get(Depsgraph * depsgraph,Scene * scene,Object * ob,bGPDlayer * gpl)603 bGPDframe *BKE_gpencil_frame_retime_get(Depsgraph *depsgraph,
604 Scene *scene,
605 Object *ob,
606 bGPDlayer *gpl)
607 {
608 int remap_cfra = gpencil_remap_time_get(depsgraph, scene, ob, gpl);
609 bGPDframe *gpf = BKE_gpencil_layer_frame_get(gpl, remap_cfra, GP_GETFRAME_USE_PREV);
610
611 return gpf;
612 }
613
gpencil_assign_object_eval(Object * object)614 static void gpencil_assign_object_eval(Object *object)
615 {
616 BLI_assert(object->id.tag & LIB_TAG_COPIED_ON_WRITE);
617
618 bGPdata *gpd_eval = object->runtime.gpd_eval;
619
620 gpd_eval->id.tag |= LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT;
621
622 if (object->id.tag & LIB_TAG_COPIED_ON_WRITE) {
623 object->data = gpd_eval;
624 }
625 }
626
627 /* Helper: Copy active frame from original datablock to evaluated datablock for modifiers. */
gpencil_copy_activeframe_to_eval(Depsgraph * depsgraph,Scene * scene,Object * ob,bGPdata * gpd_orig,bGPdata * gpd_eval)628 static void gpencil_copy_activeframe_to_eval(
629 Depsgraph *depsgraph, Scene *scene, Object *ob, bGPdata *gpd_orig, bGPdata *gpd_eval)
630 {
631
632 bGPDlayer *gpl_eval = gpd_eval->layers.first;
633 LISTBASE_FOREACH (bGPDlayer *, gpl_orig, &gpd_orig->layers) {
634
635 if (gpl_eval != NULL) {
636 int remap_cfra = gpencil_remap_time_get(depsgraph, scene, ob, gpl_orig);
637
638 bGPDframe *gpf_orig = BKE_gpencil_layer_frame_get(
639 gpl_orig, remap_cfra, GP_GETFRAME_USE_PREV);
640
641 if (gpf_orig != NULL) {
642 int gpf_index = BLI_findindex(&gpl_orig->frames, gpf_orig);
643 bGPDframe *gpf_eval = BLI_findlink(&gpl_eval->frames, gpf_index);
644
645 if (gpf_eval != NULL) {
646 /* Delete old strokes. */
647 BKE_gpencil_free_strokes(gpf_eval);
648 /* Copy again strokes. */
649 BKE_gpencil_frame_copy_strokes(gpf_orig, gpf_eval);
650
651 gpf_eval->runtime.gpf_orig = (bGPDframe *)gpf_orig;
652 BKE_gpencil_frame_original_pointers_update(gpf_orig, gpf_eval);
653 }
654 }
655
656 gpl_eval = gpl_eval->next;
657 }
658 }
659 }
660
gpencil_copy_for_eval(bGPdata * gpd)661 static bGPdata *gpencil_copy_for_eval(bGPdata *gpd)
662 {
663 const int flags = LIB_ID_COPY_LOCALIZE;
664
665 bGPdata *result = (bGPdata *)BKE_id_copy_ex(NULL, &gpd->id, NULL, flags);
666 return result;
667 }
668
669 /**
670 * Prepare grease pencil eval data for modifiers
671 * \param depsgraph: Current depsgraph
672 * \param scene: Current scene
673 * \param ob: Grease pencil object
674 */
BKE_gpencil_prepare_eval_data(Depsgraph * depsgraph,Scene * scene,Object * ob)675 void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *ob)
676 {
677 bGPdata *gpd_eval = (bGPdata *)ob->data;
678 Object *ob_orig = (Object *)DEG_get_original_id(&ob->id);
679 bGPdata *gpd_orig = (bGPdata *)ob_orig->data;
680
681 /* Need check if some layer is parented. */
682 bool do_parent = false;
683 LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_orig->layers) {
684 if (gpl->parent != NULL) {
685 do_parent = true;
686 break;
687 }
688 }
689
690 const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd_eval);
691 const bool do_modifiers = (bool)((!is_multiedit) && (ob->greasepencil_modifiers.first != NULL) &&
692 (!GPENCIL_SIMPLIFY_MODIF(scene)));
693 if ((!do_modifiers) && (!do_parent)) {
694 return;
695 }
696 DEG_debug_print_eval(depsgraph, __func__, gpd_eval->id.name, gpd_eval);
697
698 /* If only one user, don't need a new copy, just update data of the frame. */
699 if (gpd_orig->id.us == 1) {
700 ob->runtime.gpd_eval = NULL;
701 gpencil_copy_activeframe_to_eval(depsgraph, scene, ob, ob_orig->data, gpd_eval);
702 return;
703 }
704
705 /* Copy full Datablock to evaluated version. */
706 ob->runtime.gpd_orig = gpd_orig;
707 if (ob->runtime.gpd_eval != NULL) {
708 BKE_gpencil_eval_delete(ob->runtime.gpd_eval);
709 ob->runtime.gpd_eval = NULL;
710 ob->data = ob->runtime.gpd_orig;
711 }
712 ob->runtime.gpd_eval = gpencil_copy_for_eval(ob->runtime.gpd_orig);
713 gpencil_assign_object_eval(ob);
714 BKE_gpencil_update_orig_pointers(ob_orig, ob);
715 }
716
717 /** Calculate gpencil modifiers.
718 * \param depsgraph: Current depsgraph
719 * \param scene: Current scene
720 * \param ob: Grease pencil object
721 */
BKE_gpencil_modifiers_calc(Depsgraph * depsgraph,Scene * scene,Object * ob)722 void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
723 {
724 bGPdata *gpd = (bGPdata *)ob->data;
725 const bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd);
726 const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
727 const bool is_render = (bool)(DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
728 const bool do_modifiers = (bool)((!is_multiedit) && (ob->greasepencil_modifiers.first != NULL) &&
729 (!GPENCIL_SIMPLIFY_MODIF(scene)));
730 if (!do_modifiers) {
731 return;
732 }
733
734 /* Init general modifiers data. */
735 BKE_gpencil_lattice_init(ob);
736
737 const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
738
739 LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) {
740
741 if (GPENCIL_MODIFIER_ACTIVE(md, is_render)) {
742 const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(md->type);
743
744 if ((GPENCIL_MODIFIER_EDIT(md, is_edit)) && (!is_render)) {
745 continue;
746 }
747
748 /* Apply geometry modifiers (add new geometry). */
749 if (mti && mti->generateStrokes) {
750 mti->generateStrokes(md, depsgraph, ob);
751 }
752
753 /* Apply deform modifiers and Time remap (only change geometry). */
754 if ((time_remap) || (mti && mti->deformStroke)) {
755 LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
756 bGPDframe *gpf = BKE_gpencil_frame_retime_get(depsgraph, scene, ob, gpl);
757 if (gpf == NULL) {
758 continue;
759 }
760
761 if (mti->deformStroke) {
762 LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
763 mti->deformStroke(md, depsgraph, ob, gpl, gpf, gps);
764 }
765 }
766 }
767 }
768 }
769 }
770
771 /* Clear any lattice data. */
772 BKE_gpencil_lattice_clear(ob);
773 }
774