diff options
author | YimingWu <xp8110@outlook.com> | 2021-06-16 17:38:47 +0300 |
---|---|---|
committer | YimingWu <xp8110@outlook.com> | 2021-06-16 17:38:47 +0300 |
commit | 247abdbf4148843daf469285a6a63ab9cd0aeef9 (patch) | |
tree | 78a20d5175b09c83d907aaddef347536bf20aca8 /source/blender/blenkernel | |
parent | b37093de7b42cf331a4ae5830737d9972d7bb426 (diff) |
LineArt: Cached calculation for modifiers in the same stack.
This allows line art to run only once for each modifier stacks,
with an option to toggle a specific line art modifier should
use cache or re-do their own calculations.
Reviewed By: Sebastian Parborg (zeddb), Hans Goudey (HooglyBoogly)
Differential Revision: https://developer.blender.org/D11291
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_gpencil_modifier.h | 16 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/gpencil_modifier.c | 66 |
2 files changed, 82 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_gpencil_modifier.h b/source/blender/blenkernel/BKE_gpencil_modifier.h index c6406c8478c..8fbc2112c77 100644 --- a/source/blender/blenkernel/BKE_gpencil_modifier.h +++ b/source/blender/blenkernel/BKE_gpencil_modifier.h @@ -294,6 +294,22 @@ bool BKE_gpencil_has_geometry_modifiers(struct Object *ob); bool BKE_gpencil_has_time_modifiers(struct Object *ob); bool BKE_gpencil_has_transform_modifiers(struct Object *ob); +/* Stores the maximum calculation range in the whole modifier stack for line art so the cache can + * cover everything that will be visible. */ +typedef struct GpencilLineartLimitInfo { + char min_level; + char max_level; + short edge_types; +} GpencilLineartLimitInfo; + +GpencilLineartLimitInfo BKE_gpencil_get_lineart_modifier_limits(const struct Object *ob); + +void BKE_gpencil_set_lineart_modifier_limits(struct GpencilModifierData *md, + const struct GpencilLineartLimitInfo *info, + const bool is_first_lineart); +bool BKE_gpencil_is_first_lineart_in_stack(const struct Object *ob, + const struct GpencilModifierData *md); + void BKE_gpencil_lattice_init(struct Object *ob); void BKE_gpencil_lattice_clear(struct Object *ob); diff --git a/source/blender/blenkernel/intern/gpencil_modifier.c b/source/blender/blenkernel/intern/gpencil_modifier.c index 16386cac029..5ac85ad3aaf 100644 --- a/source/blender/blenkernel/intern/gpencil_modifier.c +++ b/source/blender/blenkernel/intern/gpencil_modifier.c @@ -55,6 +55,7 @@ #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" +#include "MOD_gpencil_lineart.h" #include "MOD_gpencil_modifiertypes.h" #include "BLO_read_write.h" @@ -202,6 +203,62 @@ bool BKE_gpencil_has_transform_modifiers(Object *ob) return false; } +GpencilLineartLimitInfo BKE_gpencil_get_lineart_modifier_limits(const Object *ob) +{ + GpencilLineartLimitInfo info = {0}; + bool is_first = true; + LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) { + if (md->type == eGpencilModifierType_Lineart) { + LineartGpencilModifierData *lmd = (LineartGpencilModifierData *)md; + if (is_first || (lmd->flags & LRT_GPENCIL_USE_CACHE)) { + info.min_level = MIN2(info.min_level, lmd->level_start); + info.max_level = MAX2(info.max_level, + (lmd->use_multiple_levels ? lmd->level_end : lmd->level_start)); + info.edge_types |= lmd->edge_types; + } + } + } + return info; +} + +void BKE_gpencil_set_lineart_modifier_limits(GpencilModifierData *md, + const GpencilLineartLimitInfo *info, + const bool is_first_lineart) +{ + BLI_assert(md->type == eGpencilModifierType_Lineart); + LineartGpencilModifierData *lmd = (LineartGpencilModifierData *)md; + if (is_first_lineart || lmd->flags & LRT_GPENCIL_USE_CACHE) { + lmd->level_start_override = info->min_level; + lmd->level_end_override = info->max_level; + lmd->edge_types_override = info->edge_types; + } + else { + lmd->level_start_override = lmd->level_start; + lmd->level_end_override = lmd->level_end; + lmd->edge_types_override = lmd->edge_types; + } +} + +bool BKE_gpencil_is_first_lineart_in_stack(const Object *ob, const GpencilModifierData *md) +{ + if (md->type != eGpencilModifierType_Lineart) { + return false; + } + LISTBASE_FOREACH (GpencilModifierData *, gmd, &ob->greasepencil_modifiers) { + if (gmd->type == eGpencilModifierType_Lineart) { + if (gmd == md) { + return true; + } + else { + return false; + } + } + } + /* If we reach here it means md is not in ob's modifier stack. */ + BLI_assert(false); + return false; +} + /* apply time modifiers */ static int gpencil_time_modifier( Depsgraph *depsgraph, Scene *scene, Object *ob, bGPDlayer *gpl, int cfra, bool is_render) @@ -771,6 +828,8 @@ void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob) BKE_gpencil_lattice_init(ob); const bool time_remap = BKE_gpencil_has_time_modifiers(ob); + bool is_first_lineart = true; + GpencilLineartLimitInfo info = BKE_gpencil_get_lineart_modifier_limits(ob); LISTBASE_FOREACH (GpencilModifierData *, md, &ob->greasepencil_modifiers) { @@ -781,6 +840,11 @@ void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob) continue; } + if (md->type == eGpencilModifierType_Lineart) { + BKE_gpencil_set_lineart_modifier_limits(md, &info, is_first_lineart); + is_first_lineart = false; + } + /* Apply geometry modifiers (add new geometry). */ if (mti && mti->generateStrokes) { mti->generateStrokes(md, depsgraph, ob); @@ -806,6 +870,8 @@ void BKE_gpencil_modifiers_calc(Depsgraph *depsgraph, Scene *scene, Object *ob) /* Clear any lattice data. */ BKE_gpencil_lattice_clear(ob); + + MOD_lineart_clear_cache(&gpd->runtime.lineart_cache); } void BKE_gpencil_modifier_blend_write(BlendWriter *writer, ListBase *modbase) |