diff options
Diffstat (limited to 'source')
27 files changed, 297 insertions, 42 deletions
diff --git a/source/blender/blenkernel/BKE_gpencil_modifier.h b/source/blender/blenkernel/BKE_gpencil_modifier.h index cce1d4b0a4a..5efc390015c 100644 --- a/source/blender/blenkernel/BKE_gpencil_modifier.h +++ b/source/blender/blenkernel/BKE_gpencil_modifier.h @@ -83,6 +83,8 @@ typedef enum { /* can't be added manually by user */ eGpencilModifierTypeFlag_NoUserAdd = (1 << 5), + /* can't be applied */ + eGpencilModifierTypeFlag_NoApply = (1 << 6), } GpencilModifierTypeFlag; /* IMPORTANT! Keep ObjectWalkFunc and IDWalkFunc signatures compatible. */ @@ -150,8 +152,18 @@ typedef struct GpencilModifierTypeInfo { void (*bakeModifier)(struct Main *bmain, struct Depsgraph *depsgraph, struct GpencilModifierData *md, struct Object *ob); + /********************* Optional functions *********************/ + /* Callback for GP "time" modifiers that offset keyframe time + * Returns the frame number to be used after apply the modifier. This is + * usually an offset of the animation for duplicated datablocks. + * + * This function is optional. + */ + int (*remapTime)(struct GpencilModifierData *md, struct Depsgraph *depsgraph, + struct Scene *scene, struct Object *ob, struct bGPDlayer *gpl, int cfra); + /* Initialize new instance data for this modifier type, this function * should set modifier variables to their default values. * @@ -242,6 +254,7 @@ void BKE_gpencil_modifiers_foreachIDLink(struct Object *ob, GreasePencilIDWalkFu void BKE_gpencil_modifiers_foreachTexLink(struct Object *ob, GreasePencilTexWalkFunc walk, void *userData); bool BKE_gpencil_has_geometry_modifiers(struct Object *ob); +bool BKE_gpencil_has_time_modifiers(struct Object *ob); void BKE_gpencil_stroke_modifiers( struct Depsgraph *depsgraph, struct Object *ob, @@ -249,6 +262,9 @@ void BKE_gpencil_stroke_modifiers( void BKE_gpencil_geometry_modifiers( struct Depsgraph *depsgraph, struct Object *ob, struct bGPDlayer *gpl, struct bGPDframe *gpf, bool is_render); +int BKE_gpencil_time_modifier( + struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob, + struct bGPDlayer *gpl, int cfra, bool is_render); 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 1e05a8c271c..d5c1c831c2c 100644 --- a/source/blender/blenkernel/intern/gpencil_modifier.c +++ b/source/blender/blenkernel/intern/gpencil_modifier.c @@ -402,6 +402,20 @@ bool BKE_gpencil_has_geometry_modifiers(Object *ob) return false; } +/* check if exist time modifiers */ +bool BKE_gpencil_has_time_modifiers(Object *ob) +{ + GpencilModifierData *md; + for (md = ob->greasepencil_modifiers.first; md; md = md->next) { + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); + + if (mti && mti->remapTime) { + return true; + } + } + return false; +} + /* apply stroke modifiers */ void BKE_gpencil_stroke_modifiers(Depsgraph *depsgraph, Object *ob, bGPDlayer *gpl, bGPDframe *UNUSED(gpf), bGPDstroke *gps, bool is_render) { @@ -459,6 +473,31 @@ void BKE_gpencil_geometry_modifiers(Depsgraph *depsgraph, Object *ob, bGPDlayer } } +/* apply time modifiers */ +int BKE_gpencil_time_modifier(Depsgraph *depsgraph, Scene *scene, Object *ob, + bGPDlayer *gpl, int cfra, 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)) { + continue; + } + + if (mti->remapTime) { + return mti->remapTime(md, depsgraph, scene, ob, gpl, cfra); + } + } + } + + /* if no time modifier, return original frame number */ + return cfra; +} /* *************************************************** */ void BKE_gpencil_eval_geometry(Depsgraph *depsgraph, diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c index f03947ddf87..4375d62f4b2 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c @@ -1250,12 +1250,16 @@ void DRW_gpencil_populate_datablock( View3D *v3d = draw_ctx->v3d; int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph); ToolSettings *ts = scene->toolsettings; + bGPDframe *derived_gpf = NULL; const bool main_onion = v3d != NULL ? (v3d->gp_flag & V3D_GP_SHOW_ONION_SKIN) : true; const bool do_onion = (bool)((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) && main_onion; const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) : true; + const bool time_remap = BKE_gpencil_has_time_modifiers(ob); + float opacity; bGPDframe *p = NULL; + bGPDframe *gpf = NULL; /* check if playing animation */ bool playing = stl->storage->is_playing; @@ -1274,8 +1278,16 @@ void DRW_gpencil_populate_datablock( /* don't draw layer if hidden */ if (gpl->flag & GP_LAYER_HIDE) continue; + if ((!time_remap) || (stl->storage->simplify_modif)) { + gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_USE_PREV); + } + else { + int remap_cfra = BKE_gpencil_time_modifier( + draw_ctx->depsgraph, scene,ob, gpl, cfra_eval, + stl->storage->is_render); - bGPDframe *gpf = BKE_gpencil_layer_getframe(gpl, cfra_eval, GP_GETFRAME_USE_PREV); + gpf = BKE_gpencil_layer_getframe(gpl, remap_cfra, GP_GETFRAME_USE_PREV); + } if (gpf == NULL) continue; diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index c61a8f95ee6..f5d14330499 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -1657,9 +1657,13 @@ static uiLayout *gpencil_draw_modifier( UI_block_lock_set(block, BKE_object_obdata_is_libdata(ob), ERROR_LIBDATA_MESSAGE); uiLayoutSetOperatorContext(row, WM_OP_INVOKE_DEFAULT); - uiItemEnumO(row, "OBJECT_OT_gpencil_modifier_apply", CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply"), - 0, "apply_as", MODIFIER_APPLY_DATA); + sub = uiLayoutRow(row, false); + if (mti->flags & eGpencilModifierTypeFlag_NoApply) { + uiLayoutSetEnabled(sub, false); + } + uiItemEnumO(sub, "OBJECT_OT_gpencil_modifier_apply", CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply"), + 0, "apply_as", MODIFIER_APPLY_DATA); uiItemO(row, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Copy"), ICON_NONE, "OBJECT_OT_gpencil_modifier_copy"); diff --git a/source/blender/editors/object/object_gpencil_modifier.c b/source/blender/editors/object/object_gpencil_modifier.c index cb46185a087..d67b79375e2 100644 --- a/source/blender/editors/object/object_gpencil_modifier.c +++ b/source/blender/editors/object/object_gpencil_modifier.c @@ -207,7 +207,7 @@ int ED_object_gpencil_modifier_move_down(ReportList *UNUSED(reports), Object *ob } static int gpencil_modifier_apply_obdata( - ReportList *reports, Main *bmain, Depsgraph *depsgraph, Object *ob, GpencilModifierData *md) + ReportList *reports, Main *bmain, Depsgraph *depsgraph, Object *ob, GpencilModifierData *md) { const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); @@ -269,9 +269,18 @@ int ED_object_gpencil_modifier_apply( return 1; } -int ED_object_gpencil_modifier_copy(ReportList *UNUSED(reports), Object *ob, GpencilModifierData *md) +int ED_object_gpencil_modifier_copy(ReportList *reports, Object *ob, GpencilModifierData *md) { GpencilModifierData *nmd; + const GpencilModifierTypeInfo *mti = BKE_gpencil_modifierType_getInfo(md->type); + GpencilModifierType type = md->type; + + if (mti->flags & eGpencilModifierTypeFlag_Single) { + if (BKE_gpencil_modifiers_findByType(ob, type)) { + BKE_report(reports, RPT_WARNING, "Only one modifier of this type is allowed"); + return 0; + } + } nmd = BKE_gpencil_modifier_new(md->type); BKE_gpencil_modifier_copyData(md, nmd); diff --git a/source/blender/gpencil_modifiers/CMakeLists.txt b/source/blender/gpencil_modifiers/CMakeLists.txt index 44689a1d091..00a387c58e8 100644 --- a/source/blender/gpencil_modifiers/CMakeLists.txt +++ b/source/blender/gpencil_modifiers/CMakeLists.txt @@ -58,6 +58,7 @@ set(SRC intern/MOD_gpencilsmooth.c intern/MOD_gpencilhook.c intern/MOD_gpenciloffset.c + intern/MOD_gpenciltime.c MOD_gpencil_modifiertypes.h ) diff --git a/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h index 968f7e73544..d820bbcc7c8 100644 --- a/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h +++ b/source/blender/gpencil_modifiers/MOD_gpencil_modifiertypes.h @@ -45,6 +45,7 @@ extern GpencilModifierTypeInfo modifierType_Gpencil_Smooth; extern GpencilModifierTypeInfo modifierType_Gpencil_Hook; extern GpencilModifierTypeInfo modifierType_Gpencil_Offset; extern GpencilModifierTypeInfo modifierType_Gpencil_Armature; +extern GpencilModifierTypeInfo modifierType_Gpencil_Time; /* MOD_gpencil_util.c */ void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[]); diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c index 8f5f84c2ee4..b2eeaa1c4e9 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencil_util.c @@ -78,6 +78,7 @@ void gpencil_modifier_type_init(GpencilModifierTypeInfo *types[]) INIT_GP_TYPE(Hook); INIT_GP_TYPE(Offset); INIT_GP_TYPE(Armature); + INIT_GP_TYPE(Time); #undef INIT_GP_TYPE } diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c index 5bab95cf6f6..69a48a2c93b 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilarmature.c @@ -194,7 +194,7 @@ GpencilModifierTypeInfo modifierType_Gpencil_Armature = { /* deformStroke */ deformStroke, /* generateStrokes */ NULL, /* bakeModifier */ bakeModifier, - + /* remapTime */ NULL, /* initData */ initData, /* freeData */ NULL, /* isDisabled */ isDisabled, diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c index 6435ca1ce70..0b02443f7eb 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilbuild.c @@ -515,27 +515,6 @@ static void generateStrokes( } } -/* ******************************************** */ - -/* FIXME: Baking the Build Modifier is currently unsupported. - * Adding support for this is more complicated than for other - * modifiers, as to implement this, we'd have to add more frames, - * which would in turn break how the modifier functions. - */ -#if 0 -static void bakeModifier( - Main *bmain, const Depsgraph *UNUSED(depsgraph), - GpencilModifierData *md, Object *ob) -{ - bGPdata *gpd = ob->data; - - for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) { - for (bGPDframe *gpf = gpl->frames.first; gpf; gpf = gpf->next) { - - } - } -} -#endif /* ******************************************** */ @@ -544,13 +523,14 @@ GpencilModifierTypeInfo modifierType_Gpencil_Build = { /* structName */ "BuildGpencilModifierData", /* structSize */ sizeof(BuildGpencilModifierData), /* type */ eGpencilModifierTypeType_Gpencil, - /* flags */ 0, + /* flags */ eGpencilModifierTypeFlag_NoApply, /* copyData */ copyData, /* deformStroke */ NULL, /* generateStrokes */ generateStrokes, /* bakeModifier */ NULL, + /* remapTime */ NULL, /* initData */ initData, /* freeData */ NULL, diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c index 0bbd26da670..ac1e51c62ea 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilcolor.c @@ -151,7 +151,8 @@ GpencilModifierTypeInfo modifierType_Gpencil_Color = { /* deformStroke */ deformStroke, /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, + /* bakeModifier */ bakeModifier, + /* remapTime */ NULL, /* initData */ initData, /* freeData */ NULL, diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c index 8f7911834c9..38a149fce71 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilhook.c @@ -340,7 +340,8 @@ GpencilModifierTypeInfo modifierType_Gpencil_Hook = { /* deformStroke */ deformStroke, /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, + /* bakeModifier */ bakeModifier, + /* remapTime */ NULL, /* initData */ initData, /* freeData */ freeData, diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c index 8c125ebb1cd..05912e594f5 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilinstance.c @@ -243,6 +243,7 @@ GpencilModifierTypeInfo modifierType_Gpencil_Instance = { /* deformStroke */ NULL, /* generateStrokes */ generateStrokes, /* bakeModifier */ bakeModifier, + /* remapTime */ NULL, /* initData */ initData, /* freeData */ NULL, diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c index 98bb579c662..0d7bfcfdaae 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencillattice.c @@ -198,7 +198,8 @@ GpencilModifierTypeInfo modifierType_Gpencil_Lattice = { /* deformStroke */ deformStroke, /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, + /* bakeModifier */ bakeModifier, + /* remapTime */ NULL, /* initData */ initData, /* freeData */ freeData, diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c index 4c359be670f..aec9715a995 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilmirror.c @@ -197,7 +197,8 @@ GpencilModifierTypeInfo modifierType_Gpencil_Mirror = { /* deformStroke */ NULL, /* generateStrokes */ generateStrokes, - /* bakeModifier */ bakeModifier, + /* bakeModifier */ bakeModifier, + /* remapTime */ NULL, /* initData */ initData, /* freeData */ NULL, diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c index 7ddd67337d3..aacf66d2538 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilnoise.c @@ -272,7 +272,8 @@ GpencilModifierTypeInfo modifierType_Gpencil_Noise = { /* deformStroke */ deformStroke, /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, + /* bakeModifier */ bakeModifier, + /* remapTime */ NULL, /* initData */ initData, /* freeData */ freeData, diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c index cc2e00ecc22..373fccde633 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciloffset.c @@ -130,7 +130,8 @@ GpencilModifierTypeInfo modifierType_Gpencil_Offset = { /* deformStroke */ deformStroke, /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, + /* bakeModifier */ bakeModifier, + /* remapTime */ NULL, /* initData */ initData, /* freeData */ NULL, diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c index 6314c51027e..2ccca9f3ab9 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilopacity.c @@ -171,7 +171,8 @@ GpencilModifierTypeInfo modifierType_Gpencil_Opacity = { /* deformStroke */ deformStroke, /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, + /* bakeModifier */ bakeModifier, + /* remapTime */ NULL, /* initData */ initData, /* freeData */ NULL, diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c index a8d10c973ce..a892f230d39 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsimplify.c @@ -110,7 +110,8 @@ GpencilModifierTypeInfo modifierType_Gpencil_Simplify = { /* deformStroke */ deformStroke, /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, + /* bakeModifier */ bakeModifier, + /* remapTime */ NULL, /* initData */ initData, /* freeData */ NULL, diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c index cd46ed0f2d6..01fb4c1f83b 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsmooth.c @@ -137,7 +137,8 @@ GpencilModifierTypeInfo modifierType_Gpencil_Smooth = { /* deformStroke */ deformStroke, /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, + /* bakeModifier */ bakeModifier, + /* remapTime */ NULL, /* initData */ initData, /* freeData */ NULL, diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c index 2e91c51d3da..7cf19de2020 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilsubdiv.c @@ -107,7 +107,8 @@ GpencilModifierTypeInfo modifierType_Gpencil_Subdiv = { /* deformStroke */ deformStroke, /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, + /* bakeModifier */ bakeModifier, + /* remapTime */ NULL, /* initData */ initData, /* freeData */ NULL, diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c b/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c index cffa4b0ad83..10b96cd2181 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpencilthick.c @@ -156,9 +156,10 @@ GpencilModifierTypeInfo modifierType_Gpencil_Thick = { /* copyData */ copyData, - /* deformStroke */ deformStroke, - /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, + /* deformStroke */ deformStroke, + /* generateStrokes */ NULL, + /* bakeModifier */ bakeModifier, + /* remapTime */ NULL, /* initData */ initData, /* freeData */ freeData, diff --git a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c index 98cf3ae16e7..cdbc1f465a2 100644 --- a/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c +++ b/source/blender/gpencil_modifiers/intern/MOD_gpenciltint.c @@ -159,7 +159,8 @@ GpencilModifierTypeInfo modifierType_Gpencil_Tint = { /* deformStroke */ deformStroke, /* generateStrokes */ NULL, - /* bakeModifier */ bakeModifier, + /* bakeModifier */ bakeModifier, + /* remapTime */ NULL, /* initData */ initData, /* freeData */ NULL, diff --git a/source/blender/gpencil_modifiers/intern/mod_gpenciltime.c b/source/blender/gpencil_modifiers/intern/mod_gpenciltime.c new file mode 100644 index 00000000000..32d3d69050c --- /dev/null +++ b/source/blender/gpencil_modifiers/intern/mod_gpenciltime.c @@ -0,0 +1,127 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2018, Blender Foundation + * This is a new part of Blender + * + * Contributor(s): Antonio Vazquez + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +/** \file blender/gpencil_modifiers/intern/MOD_gpenciltime.c + * \ingroup modifiers + */ + +#include <stdio.h> +#include <string.h> + +#include "BLI_utildefines.h" + +#include "DNA_meshdata_types.h" +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_gpencil_types.h" +#include "DNA_gpencil_modifier_types.h" + +#include "BKE_colortools.h" +#include "BKE_context.h" +#include "BKE_deform.h" +#include "BKE_gpencil.h" +#include "BKE_gpencil_modifier.h" + +#include "DEG_depsgraph.h" + +#include "MOD_gpencil_util.h" +#include "MOD_gpencil_modifiertypes.h" + +static void initData(GpencilModifierData *md) +{ + TimeGpencilModifierData *gpmd = (TimeGpencilModifierData *)md; + gpmd->layername[0] = '\0'; + gpmd->offset = 1; + gpmd->flag |= GP_TIME_KEEP_LOOP; +} + +static void copyData(const GpencilModifierData *md, GpencilModifierData *target) +{ + BKE_gpencil_modifier_copyData_generic(md, target); +} + +static int remapTime(struct GpencilModifierData *md, struct Depsgraph *UNUSED(depsgraph), + struct Scene *scene, struct Object *ob, struct bGPDlayer *gpl, int cfra) +{ + TimeGpencilModifierData *mmd = (TimeGpencilModifierData *)md; + const int sfra = scene->r.sfra; + const int efra = scene->r.efra; + const int nfra = cfra + mmd->offset; + + const bool invgpl = mmd->flag & GP_SIMPLIFY_INVERT_LAYER; + + /* omit if filter by layer */ + if (mmd->layername[0] != '\0') { + if (invgpl == false) { + if (!STREQ(mmd->layername, gpl->info)) { + return cfra; + } + } + else { + if (STREQ(mmd->layername, gpl->info)) { + return cfra; + } + } + } + + if (mmd->flag & GP_TIME_KEEP_LOOP) { + /* if the sum of the cfra is out scene frame range, recalc */ + if (cfra + mmd->offset < sfra) { + const int delta = abs(sfra - nfra); + return efra - delta + 1; + } + else if (cfra + mmd->offset > efra) { + return nfra - efra + sfra - 1; + } + } + + return cfra + mmd->offset; +} + +GpencilModifierTypeInfo modifierType_Gpencil_Time = { + /* name */ "Time", + /* structName */ "TimeGpencilModifierData", + /* structSize */ sizeof(TimeGpencilModifierData), + /* type */ eGpencilModifierTypeType_Gpencil, + /* flags */ eGpencilModifierTypeFlag_Single | + eGpencilModifierTypeFlag_NoApply, + + /* copyData */ copyData, + + /* deformStroke */ NULL, + /* generateStrokes */ NULL, + /* bakeModifier */ NULL, + /* remapTime */ remapTime, + + /* initData */ initData, + /* freeData */ NULL, + /* isDisabled */ NULL, + /* updateDepsgraph */ NULL, + /* dependsOnTime */ NULL, + /* foreachObjectLink */ NULL, + /* foreachIDLink */ NULL, + /* foreachTexLink */ NULL, +}; diff --git a/source/blender/makesdna/DNA_gpencil_modifier_types.h b/source/blender/makesdna/DNA_gpencil_modifier_types.h index 26b3cf934d4..fd1a4d2a2b7 100644 --- a/source/blender/makesdna/DNA_gpencil_modifier_types.h +++ b/source/blender/makesdna/DNA_gpencil_modifier_types.h @@ -51,6 +51,7 @@ typedef enum GpencilModifierType { eGpencilModifierType_Offset = 13, eGpencilModifierType_Mirror = 14, eGpencilModifierType_Armature = 15, + eGpencilModifierType_Time = 16, NUM_GREASEPENCIL_MODIFIER_TYPES } GpencilModifierType; @@ -139,6 +140,18 @@ typedef enum eThickGpencil_Flag { GP_THICK_NORMALIZE = (1 << 4), } eThickGpencil_Flag; +typedef struct TimeGpencilModifierData { + GpencilModifierData modifier; + char layername[64]; /* layer name */ + int flag; /* flags */ + int offset; +} TimeGpencilModifierData; + +typedef enum eTimeGpencil_Flag { + GP_TIME_INVERT_LAYER = (1 << 0), + GP_TIME_KEEP_LOOP = (1 << 1), +} eTimeGpencil_Flag; + typedef enum eModifyColorGpencil_Flag { GP_MODIFY_COLOR_BOTH = 0, GP_MODIFY_COLOR_STROKE = 1, diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index c1eed8093c8..0125b7c7b37 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -605,6 +605,7 @@ extern StructRNA RNA_SubdivGpencilModifier; extern StructRNA RNA_SimplifyGpencilModifier; extern StructRNA RNA_ThickGpencilModifier; extern StructRNA RNA_TintGpencilModifier; +extern StructRNA RNA_TimeGpencilModifier; extern StructRNA RNA_ColorGpencilModifier; extern StructRNA RNA_InstanceGpencilModifier; extern StructRNA RNA_DupliGpencilModifier; diff --git a/source/blender/makesrna/intern/rna_gpencil_modifier.c b/source/blender/makesrna/intern/rna_gpencil_modifier.c index cb4e4b7ca02..032cf01c57d 100644 --- a/source/blender/makesrna/intern/rna_gpencil_modifier.c +++ b/source/blender/makesrna/intern/rna_gpencil_modifier.c @@ -74,6 +74,7 @@ const EnumPropertyItem rna_enum_object_greasepencil_modifier_type_items[] = { {eGpencilModifierType_Offset, "GP_OFFSET", ICON_MOD_DISPLACE, "Offset", "Change stroke location, rotation or scale"}, {eGpencilModifierType_Smooth, "GP_SMOOTH", ICON_MOD_SMOOTH, "Smooth", "Smooth stroke"}, {eGpencilModifierType_Thick, "GP_THICK", ICON_MAN_ROT, "Thickness", "Change stroke thickness"}, + {eGpencilModifierType_Time, "GP_TIME", ICON_MOD_DISPLACE, "Time", "Offset keyframes"}, {0, "", 0, N_("Color"), "" }, {eGpencilModifierType_Color, "GP_COLOR", ICON_GROUP_VCOL, "Hue/Saturation", "Apply changes to stroke colors"}, {eGpencilModifierType_Opacity, "GP_OPACITY", ICON_MOD_MASK, "Opacity", "Opacity of the strokes"}, @@ -142,6 +143,8 @@ static StructRNA *rna_GpencilModifier_refine(struct PointerRNA *ptr) return &RNA_ThickGpencilModifier; case eGpencilModifierType_Tint: return &RNA_TintGpencilModifier; + case eGpencilModifierType_Time: + return &RNA_TimeGpencilModifier; case eGpencilModifierType_Color: return &RNA_ColorGpencilModifier; case eGpencilModifierType_Instance: @@ -719,6 +722,40 @@ static void rna_def_modifier_gpenciltint(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); } +static void rna_def_modifier_gpenciltime(BlenderRNA *brna) +{ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "TimeGpencilModifier", "GpencilModifier"); + RNA_def_struct_ui_text(srna, "Time Modifier", "Time modifier"); + RNA_def_struct_sdna(srna, "TimeGpencilModifierData"); + RNA_def_struct_ui_icon(srna, ICON_MOD_DISPLACE); + + prop = RNA_def_property(srna, "layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "layername"); + RNA_def_property_ui_text(prop, "Layer", "Layer name"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "invert_layers", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_TIME_INVERT_LAYER); + RNA_def_property_ui_text(prop, "Inverse Layers", "Inverse filter"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "offset", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "offset"); + RNA_def_property_range(prop, -INT_MAX, INT_MAX); + RNA_def_property_ui_text(prop, "Offset", + "Number of frames to offset original keyframe number"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); + + prop = RNA_def_property(srna, "use_keep_loop", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_TIME_KEEP_LOOP); + RNA_def_property_ui_text(prop, "Keep Loop", + "Retiming end frames and move to start of animation to keep loop"); + RNA_def_property_update(prop, 0, "rna_GpencilModifier_update"); +} + static void rna_def_modifier_gpencilcolor(BlenderRNA *brna) { StructRNA *srna; @@ -1392,6 +1429,7 @@ void RNA_def_greasepencil_modifier(BlenderRNA *brna) rna_def_modifier_gpencilthick(brna); rna_def_modifier_gpenciloffset(brna); rna_def_modifier_gpenciltint(brna); + rna_def_modifier_gpenciltime(brna); rna_def_modifier_gpencilcolor(brna); rna_def_modifier_gpencilinstance(brna); rna_def_modifier_gpencilbuild(brna); |