Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Vazquez <blendergit@gmail.com>2020-03-09 18:27:24 +0300
committerAntonio Vazquez <blendergit@gmail.com>2020-03-09 18:27:24 +0300
commit29f3af95272590d26f610ae828b2eeee89c82a00 (patch)
treea696a58a2561c48f7ec6166e369e22081e0a64d8 /source/blender/blenkernel/intern/gpencil_modifier.c
parentdcb93126876879d969a30a7865700abd072066f8 (diff)
GPencil: Refactor of Draw Engine, Vertex Paint and all internal functions
This commit is a full refactor of the grease pencil modules including Draw Engine, Modifiers, VFX, depsgraph update, improvements in operators and conversion of Sculpt and Weight paint tools to real brushes. Also, a huge code cleanup has been done at all levels. Thanks to @fclem for his work and yo @pepeland and @mendio for the testing and help in the development. Differential Revision: https://developer.blender.org/D6293
Diffstat (limited to 'source/blender/blenkernel/intern/gpencil_modifier.c')
-rw-r--r--source/blender/blenkernel/intern/gpencil_modifier.c358
1 files changed, 167 insertions, 191 deletions
diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c
index ebb927a7d60..1014db27d84 100644
--- a/source/blender/blenkernel/intern/gpencil_modifier.c
+++ b/source/blender/blenkernel/intern/gpencil_modifier.c
@@ -96,7 +96,7 @@ void BKE_gpencil_stroke_normal(const bGPDstroke *gps, float r_normal[3])
* Ramer - Douglas - Peucker algorithm
* by http ://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
*/
-void BKE_gpencil_simplify_stroke(bGPDstroke *gps, float epsilon)
+void BKE_gpencil_stroke_simplify_adaptive(bGPDstroke *gps, float epsilon)
{
bGPDspoint *old_points = MEM_dupallocN(gps->points);
int totpoints = gps->totpoints;
@@ -165,9 +165,6 @@ void BKE_gpencil_simplify_stroke(bGPDstroke *gps, float epsilon)
old_dvert = MEM_dupallocN(gps->dvert);
}
/* resize gps */
- gps->flag |= GP_STROKE_RECALC_GEOMETRY;
- gps->tot_triangles = 0;
-
int j = 0;
for (int i = 0; i < totpoints; i++) {
bGPDspoint *pt_src = &old_points[i];
@@ -195,13 +192,16 @@ void BKE_gpencil_simplify_stroke(bGPDstroke *gps, float epsilon)
gps->totpoints = j;
+ /* Calc geometry data. */
+ BKE_gpencil_stroke_geometry_update(gps);
+
MEM_SAFE_FREE(old_points);
MEM_SAFE_FREE(old_dvert);
MEM_SAFE_FREE(marked);
}
/* Simplify alternate vertex of stroke except extremes */
-void BKE_gpencil_simplify_fixed(bGPDstroke *gps)
+void BKE_gpencil_stroke_simplify_fixed(bGPDstroke *gps)
{
if (gps->totpoints < 5) {
return;
@@ -227,8 +227,6 @@ void BKE_gpencil_simplify_fixed(bGPDstroke *gps)
if (gps->dvert != NULL) {
gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * newtot);
}
- gps->flag |= GP_STROKE_RECALC_GEOMETRY;
- gps->tot_triangles = 0;
int j = 0;
for (int i = 0; i < gps->totpoints; i++) {
@@ -256,6 +254,8 @@ void BKE_gpencil_simplify_fixed(bGPDstroke *gps)
}
gps->totpoints = j;
+ /* Calc geometry data. */
+ BKE_gpencil_stroke_geometry_update(gps);
MEM_SAFE_FREE(old_points);
MEM_SAFE_FREE(old_dvert);
@@ -357,73 +357,8 @@ bool BKE_gpencil_has_transform_modifiers(Object *ob)
return false;
}
-/* apply stroke modifiers */
-void BKE_gpencil_stroke_modifiers(Depsgraph *depsgraph,
- Object *ob,
- bGPDlayer *gpl,
- bGPDframe *gpf,
- bGPDstroke *gps,
- bool is_render)
-{
- GpencilModifierData *md;
- bGPdata *gpd = ob->data;
- const bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd);
-
- for (md = ob->greasepencil_modifiers.first; md; md = md->next) {
- if (GPENCIL_MODIFIER_ACTIVE(md, is_render)) {
- const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
-
- if ((GPENCIL_MODIFIER_EDIT(md, is_edit)) && (!is_render)) {
- continue;
- }
-
- if (mti && mti->deformStroke) {
- mti->deformStroke(md, depsgraph, ob, gpl, gpf, gps);
- /* subdivide always requires update */
- if (md->type == eGpencilModifierType_Subdiv) {
- gps->flag |= GP_STROKE_RECALC_GEOMETRY;
- }
- /* some modifiers could require a recalc of fill triangulation data */
- else if (gpd->flag & GP_DATA_STROKE_FORCE_RECALC) {
- if (ELEM(md->type,
- eGpencilModifierType_Armature,
- eGpencilModifierType_Hook,
- eGpencilModifierType_Lattice,
- eGpencilModifierType_Offset)) {
-
- gps->flag |= GP_STROKE_RECALC_GEOMETRY;
- }
- }
- }
- }
- }
-}
-
-/* apply stroke geometry modifiers */
-void BKE_gpencil_geometry_modifiers(
- Depsgraph *depsgraph, Object *ob, bGPDlayer *gpl, bGPDframe *gpf, bool is_render)
-{
- GpencilModifierData *md;
- bGPdata *gpd = ob->data;
- const bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd);
-
- for (md = ob->greasepencil_modifiers.first; md; md = md->next) {
- if (GPENCIL_MODIFIER_ACTIVE(md, is_render)) {
- const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
-
- if ((GPENCIL_MODIFIER_EDIT(md, is_edit)) && (!is_render)) {
- continue;
- }
-
- if (mti->generateStrokes) {
- mti->generateStrokes(md, depsgraph, ob, gpl, gpf);
- }
- }
- }
-}
-
/* apply time modifiers */
-int BKE_gpencil_time_modifier(
+static int gpencil_time_modifier(
Depsgraph *depsgraph, Scene *scene, Object *ob, bGPDlayer *gpl, int cfra, bool is_render)
{
GpencilModifierData *md;
@@ -454,14 +389,14 @@ int BKE_gpencil_time_modifier(
}
/* *************************************************** */
-void BKE_gpencil_eval_geometry(Depsgraph *depsgraph, bGPdata *gpd)
+void BKE_gpencil_frame_active_set(Depsgraph *depsgraph, bGPdata *gpd)
{
DEG_debug_print_eval(depsgraph, __func__, gpd->id.name, gpd);
int ctime = (int)DEG_get_ctime(depsgraph);
/* update active frame */
- for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- gpl->actframe = BKE_gpencil_layer_getframe(gpl, ctime, GP_GETFRAME_USE_PREV);
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ gpl->actframe = BKE_gpencil_layer_frame_get(gpl, ctime, GP_GETFRAME_USE_PREV);
}
if (DEG_is_active(depsgraph)) {
@@ -471,8 +406,8 @@ void BKE_gpencil_eval_geometry(Depsgraph *depsgraph, bGPdata *gpd)
* so that editing tools work with copy-on-write
* when the current frame changes
*/
- for (bGPDlayer *gpl = gpd_orig->layers.first; gpl; gpl = gpl->next) {
- gpl->actframe = BKE_gpencil_layer_getframe(gpl, ctime, GP_GETFRAME_USE_PREV);
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_orig->layers) {
+ gpl->actframe = BKE_gpencil_layer_frame_get(gpl, ctime, GP_GETFRAME_USE_PREV);
}
}
}
@@ -687,7 +622,7 @@ GpencilModifierData *BKE_gpencil_modifiers_findByName(Object *ob, const char *na
return BLI_findstring(&(ob->greasepencil_modifiers), name, offsetof(GpencilModifierData, name));
}
-void BKE_gpencil_subdivide(bGPDstroke *gps, int level, int flag)
+void BKE_gpencil_stroke_subdivide(bGPDstroke *gps, int level, int type)
{
bGPDspoint *temp_points;
MDeformVert *temp_dverts = NULL;
@@ -710,8 +645,6 @@ void BKE_gpencil_subdivide(bGPDstroke *gps, int level, int flag)
temp_dverts = MEM_dupallocN(gps->dvert);
gps->dvert = MEM_recallocN(gps->dvert, sizeof(*gps->dvert) * gps->totpoints);
}
- gps->flag |= GP_STROKE_RECALC_GEOMETRY;
- gps->tot_triangles = 0;
/* move points from last to first to new place */
i2 = gps->totpoints - 1;
@@ -726,6 +659,7 @@ void BKE_gpencil_subdivide(bGPDstroke *gps, int level, int flag)
pt_final->flag = pt->flag;
pt_final->runtime.pt_orig = pt->runtime.pt_orig;
pt_final->runtime.idx_orig = pt->runtime.idx_orig;
+ copy_v4_v4(pt_final->vert_color, pt->vert_color);
if (gps->dvert != NULL) {
dvert = &temp_dverts[i];
@@ -749,6 +683,7 @@ void BKE_gpencil_subdivide(bGPDstroke *gps, int level, int flag)
CLAMP(pt_final->strength, GPENCIL_STRENGTH_MIN, 1.0f);
pt_final->time = interpf(pt->time, next->time, 0.5f);
pt_final->runtime.pt_orig = NULL;
+ interp_v4_v4v4(pt_final->vert_color, pt->vert_color, next->vert_color, 0.5f);
if (gps->dvert != NULL) {
dvert = &temp_dverts[i];
@@ -775,8 +710,8 @@ void BKE_gpencil_subdivide(bGPDstroke *gps, int level, int flag)
MEM_SAFE_FREE(temp_points);
MEM_SAFE_FREE(temp_dverts);
- /* move points to smooth stroke (not simple flag )*/
- if ((flag & GP_SUBDIV_SIMPLE) == 0) {
+ /* move points to smooth stroke (not simple type )*/
+ if (type != GP_SUBDIV_SIMPLE) {
/* duplicate points in a temp area with the new subdivide data */
temp_points = MEM_dupallocN(gps->points);
@@ -793,145 +728,186 @@ void BKE_gpencil_subdivide(bGPDstroke *gps, int level, int flag)
MEM_SAFE_FREE(temp_points);
}
}
+
+ /* Calc geometry data. */
+ BKE_gpencil_stroke_geometry_update(gps);
+}
+
+/* Remap frame (Time modifier) */
+static int gpencil_remap_time_get(Depsgraph *depsgraph, Scene *scene, Object *ob, bGPDlayer *gpl)
+{
+ const bool is_render = (bool)(DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
+ const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
+ int cfra_eval = (int)DEG_get_ctime(depsgraph);
+
+ int remap_cfra = cfra_eval;
+ if (time_remap) {
+ remap_cfra = gpencil_time_modifier(depsgraph, scene, ob, gpl, cfra_eval, is_render);
+ }
+
+ return remap_cfra;
}
-/* Copy frame but do not assign new memory */
-static void gpencil_frame_copy_noalloc(Object *ob, bGPDframe *gpf, bGPDframe *gpf_eval)
+/* Get the current frame retimed with time modifiers. */
+bGPDframe *BKE_gpencil_frame_retime_get(Depsgraph *depsgraph,
+ Scene *scene,
+ Object *ob,
+ bGPDlayer *gpl)
{
- gpf_eval->prev = gpf->prev;
- gpf_eval->next = gpf->next;
- gpf_eval->framenum = gpf->framenum;
- gpf_eval->flag = gpf->flag;
- gpf_eval->key_type = gpf->key_type;
- gpf_eval->runtime = gpf->runtime;
- copy_m4_m4(gpf_eval->runtime.parent_obmat, gpf->runtime.parent_obmat);
+ int remap_cfra = gpencil_remap_time_get(depsgraph, scene, ob, gpl);
+ bGPDframe *gpf = BKE_gpencil_layer_frame_get(gpl, remap_cfra, GP_GETFRAME_USE_PREV);
- /* copy strokes */
- BLI_listbase_clear(&gpf_eval->strokes);
- for (bGPDstroke *gps_src = gpf->strokes.first; gps_src; gps_src = gps_src->next) {
- /* make copy of source stroke */
- bGPDstroke *gps_dst = BKE_gpencil_stroke_duplicate(gps_src);
+ return gpf;
+}
- /* copy color to temp fields to apply temporal changes in the stroke */
- MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps_src->mat_nr + 1);
- if (gp_style) {
- copy_v4_v4(gps_dst->runtime.tmp_stroke_rgba, gp_style->stroke_rgba);
- copy_v4_v4(gps_dst->runtime.tmp_fill_rgba, gp_style->fill_rgba);
- }
+static void gpencil_assign_object_eval(Object *object)
+{
+ BLI_assert(object->id.tag & LIB_TAG_COPIED_ON_WRITE);
- /* Save original pointers for using in edit and select operators. */
- gps_dst->runtime.gps_orig = gps_src;
- for (int i = 0; i < gps_src->totpoints; i++) {
- bGPDspoint *pt_dst = &gps_dst->points[i];
- pt_dst->runtime.pt_orig = &gps_src->points[i];
- pt_dst->runtime.idx_orig = i;
- }
+ bGPdata *gpd_eval = object->runtime.gpd_eval;
+
+ gpd_eval->id.tag |= LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT;
- BLI_addtail(&gpf_eval->strokes, gps_dst);
+ if (object->id.tag & LIB_TAG_COPIED_ON_WRITE) {
+ object->data = gpd_eval;
}
}
-/* Ensure there is a evaluated frame */
-static void gpencil_evaluated_frame_ensure(int idx,
- Object *ob,
- bGPDframe *gpf,
- bGPDframe **gpf_eval)
+/* Helper: Copy active frame from original datablock to evaluated datablock for modifiers. */
+static void gpencil_copy_activeframe_to_eval(
+ Depsgraph *depsgraph, Scene *scene, Object *ob, bGPdata *gpd_orig, bGPdata *gpd_eval)
{
- /* Create evaluated frames array data or expand. */
- bGPDframe *evaluated_frames = ob->runtime.gpencil_evaluated_frames;
- *gpf_eval = &evaluated_frames[idx];
- /* If already exist a evaluated frame create a new one. */
- if (*gpf_eval != NULL) {
- /* first clear temp data */
- BKE_gpencil_free_frame_runtime_data(*gpf_eval);
+ bGPDlayer *gpl_eval = gpd_eval->layers.first;
+ LISTBASE_FOREACH (bGPDlayer *, gpl_orig, &gpd_orig->layers) {
+
+ if (gpl_eval != NULL) {
+ int remap_cfra = gpencil_remap_time_get(depsgraph, scene, ob, gpl_orig);
+
+ bGPDframe *gpf_orig = BKE_gpencil_layer_frame_get(
+ gpl_orig, remap_cfra, GP_GETFRAME_USE_PREV);
+
+ if (gpf_orig != NULL) {
+ int gpf_index = BLI_findindex(&gpl_orig->frames, gpf_orig);
+ bGPDframe *gpf_eval = BLI_findlink(&gpl_eval->frames, gpf_index);
+
+ if (gpf_eval != NULL) {
+ /* Delete old strokes. */
+ BKE_gpencil_free_strokes(gpf_eval);
+ /* Copy again strokes. */
+ BKE_gpencil_frame_copy_strokes(gpf_orig, gpf_eval);
+
+ gpf_eval->runtime.gpf_orig = (bGPDframe *)gpf_orig;
+ BKE_gpencil_frame_original_pointers_update(gpf_orig, gpf_eval);
+ }
+ }
+
+ gpl_eval = gpl_eval->next;
+ }
}
- /* Copy data (do not assign new memory). */
- gpencil_frame_copy_noalloc(ob, gpf, *gpf_eval);
}
-/* Calculate gpencil modifiers */
-void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
+static bGPdata *gpencil_copy_for_eval(bGPdata *gpd)
{
- /* use original data to set reference pointers to original data */
- Object *ob_orig = DEG_get_original_object(ob);
- bGPdata *gpd = (bGPdata *)ob_orig->data;
- const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
- const bool simplify_modif = GPENCIL_SIMPLIFY_MODIF(scene, false);
- const bool is_render = (bool)(DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
- const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
- int cfra_eval = (int)DEG_get_ctime(depsgraph);
+ int flags = LIB_ID_COPY_LOCALIZE;
+
+ bGPdata *result;
+ BKE_id_copy_ex(NULL, &gpd->id, (ID **)&result, flags);
+ return result;
+}
- /* Clear any previous evaluated data. */
- if (ob->runtime.gpencil_tot_layers > 0) {
- for (int i = 0; i < ob->runtime.gpencil_tot_layers; i++) {
- bGPDframe *gpf_eval = &ob->runtime.gpencil_evaluated_frames[i];
- BKE_gpencil_free_frame_runtime_data(gpf_eval);
+void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *ob)
+{
+ bGPdata *gpd_eval = (bGPdata *)ob->data;
+ Object *ob_orig = (Object *)DEG_get_original_id(&ob->id);
+ bGPdata *gpd_orig = (bGPdata *)ob_orig->data;
+
+ /* Need check if some layer is parented. */
+ bool do_parent = false;
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_orig->layers) {
+ if (gpl->parent != NULL) {
+ do_parent = true;
+ break;
}
}
- /* Create array of evaluated frames equal to number of layers. */
- ob->runtime.gpencil_tot_layers = BLI_listbase_count(&gpd->layers);
- CLAMP_MIN(ob->runtime.gpencil_tot_layers, 1);
- if (ob->runtime.gpencil_evaluated_frames == NULL) {
- ob->runtime.gpencil_evaluated_frames = MEM_callocN(
- sizeof(struct bGPDframe) * ob->runtime.gpencil_tot_layers, __func__);
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd_eval);
+ const bool do_modifiers = (bool)((!is_multiedit) && (ob->greasepencil_modifiers.first != NULL) &&
+ (!GPENCIL_SIMPLIFY_MODIF(scene)));
+ if ((!do_modifiers) && (!do_parent)) {
+ return;
+ }
+ DEG_debug_print_eval(depsgraph, __func__, gpd_eval->id.name, gpd_eval);
+
+ /* If only one user, don't need a new copy, just update data of the frame. */
+ if (gpd_orig->id.us == 1) {
+ ob->runtime.gpd_eval = NULL;
+ gpencil_copy_activeframe_to_eval(depsgraph, scene, ob, ob_orig->data, gpd_eval);
+ return;
}
- else {
- ob->runtime.gpencil_evaluated_frames = MEM_recallocN(ob->runtime.gpencil_evaluated_frames,
- sizeof(struct bGPDframe) *
- ob->runtime.gpencil_tot_layers);
+
+ /* Copy full Datablock to evaluated version. */
+ ob->runtime.gpd_orig = gpd_orig;
+ if (ob->runtime.gpd_eval != NULL) {
+ BKE_gpencil_eval_delete(ob->runtime.gpd_eval);
+ ob->runtime.gpd_eval = NULL;
+ ob->data = ob->runtime.gpd_orig;
+ }
+ ob->runtime.gpd_eval = gpencil_copy_for_eval(ob->runtime.gpd_orig);
+ gpencil_assign_object_eval(ob);
+ BKE_gpencil_update_orig_pointers(ob_orig, (Object *)ob);
+}
+
+/* Calculate gpencil modifiers */
+void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob)
+{
+ bGPdata *gpd = (bGPdata *)ob->data;
+ const bool is_edit = GPENCIL_ANY_EDIT_MODE(gpd);
+ const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd);
+ const bool is_render = (bool)(DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
+ const bool do_modifiers = (bool)((!is_multiedit) && (ob->greasepencil_modifiers.first != NULL) &&
+ (!GPENCIL_SIMPLIFY_MODIF(scene)));
+ if (!do_modifiers) {
+ return;
}
/* Init general modifiers data. */
- if (ob->greasepencil_modifiers.first) {
- BKE_gpencil_lattice_init(ob);
- }
-
- /* *****************************************************************
- * Loop all layers, duplicate data and apply modifiers.
- *
- * ******************************************************************/
- int idx = 0;
- for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- /* Remap frame (Time modifier) */
- int remap_cfra = cfra_eval;
- if ((time_remap) && (!simplify_modif)) {
- remap_cfra = BKE_gpencil_time_modifier(depsgraph, scene, ob, gpl, cfra_eval, is_render);
- }
- bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, remap_cfra, GP_GETFRAME_USE_PREV);
+ BKE_gpencil_lattice_init(ob);
- if (gpf == NULL) {
- idx++;
- continue;
- }
+ const bool time_remap = BKE_gpencil_has_time_modifiers(ob);
- /* Create a duplicate data set of stroke to modify. */
- bGPDframe *gpf_eval = NULL;
- gpencil_evaluated_frame_ensure(idx, ob, gpf, &gpf_eval);
+ LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) {
- /* Skip all if some disable flag is enabled. */
- if ((ob->greasepencil_modifiers.first == NULL) || (is_multiedit) || (simplify_modif)) {
- idx++;
- continue;
- }
+ if (GPENCIL_MODIFIER_ACTIVE(md, is_render)) {
+ const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type);
- /* Apply geometry modifiers (create new geometry). */
- if (BKE_gpencil_has_geometry_modifiers(ob)) {
- BKE_gpencil_geometry_modifiers(depsgraph, ob, gpl, gpf_eval, is_render);
- }
+ if ((GPENCIL_MODIFIER_EDIT(md, is_edit)) && (!is_render)) {
+ continue;
+ }
- /* Loop all strokes and deform them. */
- for (bGPDstroke *gps = gpf_eval->strokes.first; gps; gps = gps->next) {
- /* Apply modifiers that only deform geometry */
- BKE_gpencil_stroke_modifiers(depsgraph, ob, gpl, gpf_eval, gps, is_render);
- }
+ /* Apply geometry modifiers (add new geometry). */
+ if (mti && mti->generateStrokes) {
+ mti->generateStrokes(md, depsgraph, ob);
+ }
- idx++;
+ /* Apply deform modifiers and Time remap (only change geometry). */
+ if ((time_remap) || (mti && mti->deformStroke)) {
+ LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
+ bGPDframe *gpf = BKE_gpencil_frame_retime_get(depsgraph, scene, ob, gpl);
+ if (gpf == NULL) {
+ continue;
+ }
+
+ if (mti->deformStroke) {
+ LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
+ mti->deformStroke(md, depsgraph, ob, gpl, gpf, gps);
+ }
+ }
+ }
+ }
+ }
}
/* Clear any lattice data. */
- if (ob->greasepencil_modifiers.first) {
- BKE_gpencil_lattice_clear(ob);
- }
+ BKE_gpencil_lattice_clear(ob);
}