GPv3: Add initial dopesheet support
This PR adds basic support for viewing layers and keyframes in the grease pencil dopsheet for the new grease pencil data-type. Resolves #108508. Co-authored-by: Amelie Fondevilla <amelie.fondevilla@les-fees-speciales.coop> Pull Request: https://projects.blender.org/blender/blender/pulls/108807
This commit is contained in:
@@ -56,6 +56,7 @@ static void grease_pencil_init_data(ID *id)
|
||||
|
||||
new (&grease_pencil->root_group) greasepencil::LayerGroup();
|
||||
grease_pencil->active_layer = nullptr;
|
||||
grease_pencil->flag |= GREASE_PENCIL_ANIM_CHANNEL_EXPANDED;
|
||||
}
|
||||
|
||||
static void grease_pencil_copy_data(Main * /*bmain*/,
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_curves_types.h"
|
||||
#include "DNA_gpencil_legacy_types.h"
|
||||
#include "DNA_grease_pencil_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_lattice_types.h"
|
||||
#include "DNA_light_types.h"
|
||||
@@ -51,6 +52,7 @@
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_gpencil_legacy.h"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_main.h"
|
||||
@@ -3319,7 +3321,7 @@ static bAnimChannelType ACF_SHAPEKEY = {
|
||||
/*setting_ptr*/ acf_shapekey_setting_ptr,
|
||||
};
|
||||
|
||||
/* GPencil Datablock ------------------------------------------- */
|
||||
/* GPencil Datablock (Legacy) ------------------------------------------- */
|
||||
|
||||
/* get backdrop color for gpencil datablock widget */
|
||||
static void acf_gpd_color(bAnimContext * /*ac*/, bAnimListElem * /*ale*/, float r_color[3])
|
||||
@@ -3351,7 +3353,9 @@ static bool acf_gpd_setting_valid(bAnimContext * /*ac*/,
|
||||
}
|
||||
|
||||
/* Get the appropriate flag(s) for the setting when it is valid. */
|
||||
static int acf_gpd_setting_flag(bAnimContext * /*ac*/, eAnimChannel_Settings setting, bool *r_neg)
|
||||
static int acf_gpd_setting_flag_legacy(bAnimContext * /*ac*/,
|
||||
eAnimChannel_Settings setting,
|
||||
bool *r_neg)
|
||||
{
|
||||
/* Clear extra return data first. */
|
||||
*r_neg = false;
|
||||
@@ -3370,19 +3374,70 @@ static int acf_gpd_setting_flag(bAnimContext * /*ac*/, eAnimChannel_Settings set
|
||||
}
|
||||
|
||||
/* get pointer to the setting */
|
||||
static void *acf_gpd_setting_ptr_legacy(bAnimListElem *ale,
|
||||
eAnimChannel_Settings /*setting*/,
|
||||
short *r_type)
|
||||
{
|
||||
bGPdata *grease_pencil = (bGPdata *)ale->data;
|
||||
|
||||
/* all flags are just in gpd->flag for now... */
|
||||
return GET_ACF_FLAG_PTR(grease_pencil->flag, r_type);
|
||||
}
|
||||
|
||||
/** Grease-pencil data-block type define. (Legacy) */
|
||||
static bAnimChannelType ACF_GPD_LEGACY = {
|
||||
/*channel_type_name*/ "GPencil Datablock",
|
||||
/*channel_role*/ ACHANNEL_ROLE_EXPANDER,
|
||||
|
||||
/*get_backdrop_color*/ acf_gpd_color,
|
||||
/*draw_backdrop*/ acf_group_backdrop,
|
||||
/*get_indent_level*/ acf_generic_indentation_0,
|
||||
/*get_offset*/ acf_generic_group_offset,
|
||||
|
||||
/*name*/ acf_generic_idblock_name,
|
||||
/*name_prop*/ acf_generic_idfill_name_prop,
|
||||
/*icon*/ acf_gpd_icon,
|
||||
|
||||
/*has_setting*/ acf_gpd_setting_valid,
|
||||
/*setting_flag*/ acf_gpd_setting_flag_legacy,
|
||||
/*setting_ptr*/ acf_gpd_setting_ptr_legacy,
|
||||
};
|
||||
|
||||
/* Grease Pencil Datablock ------------------------------------------- */
|
||||
|
||||
/* Get pointer to the setting */
|
||||
static void *acf_gpd_setting_ptr(bAnimListElem *ale,
|
||||
eAnimChannel_Settings /*setting*/,
|
||||
short *r_type)
|
||||
{
|
||||
bGPdata *gpd = (bGPdata *)ale->data;
|
||||
GreasePencil *grease_pencil = (GreasePencil *)ale->data;
|
||||
|
||||
/* all flags are just in gpd->flag for now... */
|
||||
return GET_ACF_FLAG_PTR(gpd->flag, r_type);
|
||||
return GET_ACF_FLAG_PTR(grease_pencil->flag, r_type);
|
||||
}
|
||||
|
||||
/* Get the appropriate flag(s) for the setting when it is valid. */
|
||||
static int acf_gpd_setting_flag(bAnimContext * /*ac*/, eAnimChannel_Settings setting, bool *r_neg)
|
||||
{
|
||||
/* Clear extra return data first. */
|
||||
*r_neg = false;
|
||||
|
||||
switch (setting) {
|
||||
case ACHANNEL_SETTING_SELECT: /* Selected */
|
||||
return AGRP_SELECTED;
|
||||
|
||||
case ACHANNEL_SETTING_EXPAND: /* Expanded */
|
||||
return GREASE_PENCIL_ANIM_CHANNEL_EXPANDED;
|
||||
|
||||
default:
|
||||
/* This shouldn't happen */
|
||||
BLI_assert_msg(true, "Unexpected channel flag");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** Grease-pencil data-block type define. */
|
||||
static bAnimChannelType ACF_GPD = {
|
||||
/*channel_type_name*/ "GPencil Datablock",
|
||||
/*channel_type_name*/ "Grease Pencil Datablock",
|
||||
/*channel_role*/ ACHANNEL_ROLE_EXPANDER,
|
||||
|
||||
/*get_backdrop_color*/ acf_gpd_color,
|
||||
@@ -3399,10 +3454,10 @@ static bAnimChannelType ACF_GPD = {
|
||||
/*setting_ptr*/ acf_gpd_setting_ptr,
|
||||
};
|
||||
|
||||
/* GPencil Layer ------------------------------------------- */
|
||||
/* GPencil Layer (Legacy) ------------------------------------------- */
|
||||
|
||||
/* name for grease pencil layer entries */
|
||||
static void acf_gpl_name(bAnimListElem *ale, char *name)
|
||||
static void acf_gpl_name_legacy(bAnimListElem *ale, char *name)
|
||||
{
|
||||
bGPDlayer *gpl = (bGPDlayer *)ale->data;
|
||||
|
||||
@@ -3412,7 +3467,7 @@ static void acf_gpl_name(bAnimListElem *ale, char *name)
|
||||
}
|
||||
|
||||
/* name property for grease pencil layer entries */
|
||||
static bool acf_gpl_name_prop(bAnimListElem *ale, PointerRNA *r_ptr, PropertyRNA **r_prop)
|
||||
static bool acf_gpl_name_prop_legacy(bAnimListElem *ale, PointerRNA *r_ptr, PropertyRNA **r_prop)
|
||||
{
|
||||
if (ale->data) {
|
||||
RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, r_ptr);
|
||||
@@ -3469,9 +3524,9 @@ static int acf_gpl_setting_flag(bAnimContext * /*ac*/, eAnimChannel_Settings set
|
||||
}
|
||||
|
||||
/* get pointer to the setting */
|
||||
static void *acf_gpl_setting_ptr(bAnimListElem *ale,
|
||||
eAnimChannel_Settings /*setting*/,
|
||||
short *r_type)
|
||||
static void *acf_gpl_setting_ptr_legacy(bAnimListElem *ale,
|
||||
eAnimChannel_Settings /*setting*/,
|
||||
short *r_type)
|
||||
{
|
||||
bGPDlayer *gpl = (bGPDlayer *)ale->data;
|
||||
|
||||
@@ -3480,7 +3535,7 @@ static void *acf_gpl_setting_ptr(bAnimListElem *ale,
|
||||
}
|
||||
|
||||
/** Grease-pencil layer type define. */
|
||||
static bAnimChannelType ACF_GPL = {
|
||||
static bAnimChannelType ACF_GPL_LEGACY = {
|
||||
/*channel_type_name*/ "GPencil Layer",
|
||||
/*channel_role*/ ACHANNEL_ROLE_CHANNEL,
|
||||
|
||||
@@ -3489,9 +3544,64 @@ static bAnimChannelType ACF_GPL = {
|
||||
/*get_indent_level*/ acf_generic_indentation_flexible,
|
||||
/*get_offset*/ acf_generic_group_offset,
|
||||
|
||||
/*name*/ acf_gpl_name_legacy,
|
||||
/*name_prop*/ acf_gpl_name_prop_legacy,
|
||||
/*icon*/ nullptr,
|
||||
|
||||
/*has_setting*/ acf_gpl_setting_valid,
|
||||
/*setting_flag*/ acf_gpl_setting_flag,
|
||||
/*setting_ptr*/ acf_gpl_setting_ptr_legacy,
|
||||
};
|
||||
|
||||
/* Grease Pencil Layer ------------------------------------------- */
|
||||
|
||||
/* Name for grease pencil layer entries */
|
||||
static void acf_gpl_name(bAnimListElem *ale, char *name)
|
||||
{
|
||||
GreasePencilLayer *layer = (GreasePencilLayer *)ale->data;
|
||||
|
||||
if (layer && name) {
|
||||
BLI_strncpy(name, layer->wrap().name().c_str(), ANIM_CHAN_NAME_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Name property for grease pencil layer entries */
|
||||
static bool acf_gpl_name_prop(bAnimListElem *ale, PointerRNA *r_ptr, PropertyRNA **r_prop)
|
||||
{
|
||||
if (ale->data == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RNA_pointer_create(ale->id, &RNA_GreasePencilLayer, ale->data, r_ptr);
|
||||
*r_prop = RNA_struct_name_property(r_ptr->type);
|
||||
|
||||
return (*r_prop != nullptr);
|
||||
}
|
||||
|
||||
/* Get pointer to the setting */
|
||||
static void *acf_gpl_setting_ptr(bAnimListElem *ale,
|
||||
eAnimChannel_Settings /*setting*/,
|
||||
short *r_type)
|
||||
{
|
||||
GreasePencilLayer *layer = (GreasePencilLayer *)ale->data;
|
||||
|
||||
/* All flags are just in gpl->flag for now... */
|
||||
return GET_ACF_FLAG_PTR(layer->base.flag, r_type);
|
||||
}
|
||||
|
||||
/** Grease-pencil layer type define. */
|
||||
static bAnimChannelType ACF_GPL = {
|
||||
/*channel_type_name*/ "Grease Pencil Layer",
|
||||
/*channel_role*/ ACHANNEL_ROLE_CHANNEL,
|
||||
|
||||
/*get_backdrop_color*/ acf_gpencil_channel_color,
|
||||
/*draw_backdrop*/ acf_generic_channel_backdrop,
|
||||
/*get_indent_level*/ acf_generic_indentation_flexible,
|
||||
/*get_offset*/ acf_generic_group_offset,
|
||||
|
||||
/*name*/ acf_gpl_name,
|
||||
/*name_prop*/ acf_gpl_name_prop,
|
||||
/*icon*/ nullptr,
|
||||
/*icon*/ NULL,
|
||||
|
||||
/*has_setting*/ acf_gpl_setting_valid,
|
||||
/*setting_flag*/ acf_gpl_setting_flag,
|
||||
@@ -4056,6 +4166,9 @@ static void ANIM_init_channel_typeinfo_data()
|
||||
|
||||
animchannelTypeInfo[type++] = &ACF_SHAPEKEY; /* ShapeKey */
|
||||
|
||||
animchannelTypeInfo[type++] = &ACF_GPD_LEGACY; /* Grease Pencil Datablock (Legacy) */
|
||||
animchannelTypeInfo[type++] = &ACF_GPL_LEGACY; /* Grease Pencil Layer (Legacy) */
|
||||
|
||||
animchannelTypeInfo[type++] = &ACF_GPD; /* Grease Pencil Datablock */
|
||||
animchannelTypeInfo[type++] = &ACF_GPL; /* Grease Pencil Layer */
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "DNA_camera_types.h"
|
||||
#include "DNA_curves_types.h"
|
||||
#include "DNA_gpencil_legacy_types.h"
|
||||
#include "DNA_grease_pencil_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_lattice_types.h"
|
||||
#include "DNA_layer_types.h"
|
||||
@@ -73,6 +74,7 @@
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_fcurve_driver.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_layer.h"
|
||||
#include "BKE_main.h"
|
||||
@@ -961,6 +963,15 @@ static bAnimListElem *make_new_animlistelem(void *data,
|
||||
ale->datatype = ALE_GPFRAME;
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_GREASE_PENCIL_LAYER: {
|
||||
GreasePencilLayer *layer = (GreasePencilLayer *)data;
|
||||
|
||||
ale->flag = layer->base.flag;
|
||||
|
||||
ale->key_data = nullptr;
|
||||
ale->datatype = ALE_GREASE_PENCIL_CELS;
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_MASKLAYER: {
|
||||
MaskLayer *masklay = (MaskLayer *)data;
|
||||
|
||||
@@ -1772,11 +1783,39 @@ static size_t animdata_filter_gpencil_layers_data(ListBase *anim_data,
|
||||
return items;
|
||||
}
|
||||
|
||||
static size_t animdata_filter_grease_pencil_data(ListBase *anim_data,
|
||||
bDopeSheet * /*ads*/,
|
||||
GreasePencil *grease_pencil,
|
||||
int filter_mode)
|
||||
{
|
||||
using namespace blender;
|
||||
|
||||
size_t items = 0;
|
||||
|
||||
/* Add data block container */
|
||||
ANIMCHANNEL_NEW_CHANNEL(grease_pencil, ANIMTYPE_GREASE_PENCIL_DATABLOCK, grease_pencil, nullptr);
|
||||
|
||||
Span<bke::greasepencil::Layer *> layers = grease_pencil->layers_for_write();
|
||||
|
||||
BEGIN_ANIMFILTER_SUBCHANNELS (grease_pencil->flag &GREASE_PENCIL_ANIM_CHANNEL_EXPANDED) {
|
||||
for (int64_t layer_index = layers.size() - 1; layer_index >= 0; layer_index--) {
|
||||
bke::greasepencil::Layer *layer = layers[layer_index];
|
||||
|
||||
/* Add layer channel */
|
||||
ANIMCHANNEL_NEW_CHANNEL(
|
||||
static_cast<void *>(layer), ANIMTYPE_GREASE_PENCIL_LAYER, grease_pencil, nullptr);
|
||||
}
|
||||
}
|
||||
END_ANIMFILTER_SUBCHANNELS;
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
/* Helper for Grease Pencil - Grease Pencil data-block - GP Frames. */
|
||||
static size_t animdata_filter_gpencil_data(ListBase *anim_data,
|
||||
bDopeSheet *ads,
|
||||
bGPdata *gpd,
|
||||
int filter_mode)
|
||||
static size_t animdata_filter_gpencil_legacy_data(ListBase *anim_data,
|
||||
bDopeSheet *ads,
|
||||
bGPdata *gpd,
|
||||
int filter_mode)
|
||||
{
|
||||
size_t items = 0;
|
||||
|
||||
@@ -1818,15 +1857,64 @@ static size_t animdata_filter_gpencil_data(ListBase *anim_data,
|
||||
return items;
|
||||
}
|
||||
|
||||
static size_t animdata_filter_grease_pencil(bAnimContext *ac, ListBase *anim_data, int filter_mode)
|
||||
{
|
||||
size_t items = 0;
|
||||
Scene *scene = ac->scene;
|
||||
ViewLayer *view_layer = (ViewLayer *)ac->view_layer;
|
||||
bDopeSheet *ads = ac->ads;
|
||||
|
||||
BKE_view_layer_synced_ensure(scene, view_layer);
|
||||
LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
|
||||
if (!base->object || (base->object->type != OB_GREASE_PENCIL)) {
|
||||
continue;
|
||||
}
|
||||
Object *ob = base->object;
|
||||
|
||||
if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
|
||||
/* Layer visibility - we check both object and base,
|
||||
* since these may not be in sync yet. */
|
||||
if ((base->flag & BASE_ENABLED_AND_MAYBE_VISIBLE_IN_VIEWPORT) == 0 ||
|
||||
(base->flag & BASE_ENABLED_AND_VISIBLE_IN_DEFAULT_VIEWPORT) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Outliner restrict-flag */
|
||||
if (ob->visibility_flag & OB_HIDE_VIEWPORT) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check selection and object type filters */
|
||||
if ((ads->filterflag & ADS_FILTER_ONLYSEL) && !(base->flag & BASE_SELECTED)) {
|
||||
/* Only selected should be shown */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ads->filter_grp != nullptr) {
|
||||
if (BKE_collection_has_object_recursive(ads->filter_grp, ob) == 0) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
items += animdata_filter_grease_pencil_data(
|
||||
anim_data, ads, static_cast<GreasePencil *>(ob->data), filter_mode);
|
||||
}
|
||||
|
||||
/* Return the number of items added to the list */
|
||||
return items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Grab all Grease Pencil data-blocks in file.
|
||||
*
|
||||
* TODO: should this be amalgamated with the dope-sheet filtering code?
|
||||
*/
|
||||
static size_t animdata_filter_gpencil(bAnimContext *ac,
|
||||
ListBase *anim_data,
|
||||
void * /*data*/,
|
||||
int filter_mode)
|
||||
static size_t animdata_filter_gpencil_legacy(bAnimContext *ac,
|
||||
ListBase *anim_data,
|
||||
void * /*data*/,
|
||||
int filter_mode)
|
||||
{
|
||||
bDopeSheet *ads = ac->ads;
|
||||
size_t items = 0;
|
||||
@@ -1839,7 +1927,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac,
|
||||
{
|
||||
LISTBASE_FOREACH (bGPdata *, gpd, &ac->bmain->gpencils) {
|
||||
if (gpd->flag & GP_DATA_ANNOTATIONS) {
|
||||
items += animdata_filter_gpencil_data(anim_data, ads, gpd, filter_mode);
|
||||
items += animdata_filter_gpencil_legacy_data(anim_data, ads, gpd, filter_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1892,7 +1980,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac,
|
||||
|
||||
/* finally, include this object's grease pencil data-block. */
|
||||
/* XXX: Should we store these under expanders per item? */
|
||||
items += animdata_filter_gpencil_data(
|
||||
items += animdata_filter_gpencil_legacy_data(
|
||||
anim_data, ads, static_cast<bGPdata *>(ob->data), filter_mode);
|
||||
}
|
||||
}
|
||||
@@ -3490,7 +3578,12 @@ size_t ANIM_animdata_filter(bAnimContext *ac,
|
||||
/* Modes for Specialty Data Types (i.e. not keyframes) */
|
||||
case ANIMCONT_GPENCIL: {
|
||||
if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items)) {
|
||||
items = animdata_filter_gpencil(ac, anim_data, data, filter_mode);
|
||||
if (U.experimental.use_grease_pencil_version3) {
|
||||
items = animdata_filter_grease_pencil(ac, anim_data, filter_mode);
|
||||
}
|
||||
else {
|
||||
items = animdata_filter_gpencil_legacy(ac, anim_data, data, filter_mode);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_gpencil_legacy_types.h"
|
||||
#include "DNA_grease_pencil_types.h"
|
||||
#include "DNA_mask_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
@@ -381,6 +382,7 @@ enum eAnimKeylistDrawListElemType {
|
||||
ANIM_KEYLIST_FCURVE,
|
||||
ANIM_KEYLIST_ACTION,
|
||||
ANIM_KEYLIST_AGROUP,
|
||||
ANIM_KEYLIST_GREASE_PENCIL_CELS,
|
||||
ANIM_KEYLIST_GP_LAYER,
|
||||
ANIM_KEYLIST_MASK_LAYER,
|
||||
};
|
||||
@@ -404,6 +406,7 @@ struct AnimKeylistDrawListElem {
|
||||
bAction *act;
|
||||
bActionGroup *agrp;
|
||||
bGPDlayer *gpl;
|
||||
GreasePencilLayer *grease_pencil_layer;
|
||||
MaskLayer *masklay;
|
||||
};
|
||||
|
||||
@@ -434,6 +437,11 @@ static void ED_keylist_draw_list_elem_build_keylist(AnimKeylistDrawListElem *ele
|
||||
agroup_to_keylist(elem->adt, elem->agrp, elem->keylist, elem->saction_flag);
|
||||
break;
|
||||
}
|
||||
case ANIM_KEYLIST_GREASE_PENCIL_CELS: {
|
||||
grease_pencil_cels_to_keylist(
|
||||
elem->adt, elem->grease_pencil_layer, elem->keylist, elem->saction_flag);
|
||||
break;
|
||||
}
|
||||
case ANIM_KEYLIST_GP_LAYER: {
|
||||
gpl_to_keylist(elem->ads, elem->gpl, elem->keylist);
|
||||
break;
|
||||
@@ -698,6 +706,18 @@ void draw_action_channel(AnimKeylistDrawList *draw_list,
|
||||
draw_elem->channel_locked = locked;
|
||||
}
|
||||
|
||||
void draw_grease_pencil_cels_channel(AnimKeylistDrawList *draw_list,
|
||||
bDopeSheet * /*ads*/,
|
||||
GreasePencilLayer *layer,
|
||||
const float ypos,
|
||||
const float yscale_fac,
|
||||
int saction_flag)
|
||||
{
|
||||
AnimKeylistDrawListElem *draw_elem = ed_keylist_draw_list_add_elem(
|
||||
draw_list, ANIM_KEYLIST_GREASE_PENCIL_CELS, ypos, yscale_fac, eSAction_Flag(saction_flag));
|
||||
draw_elem->grease_pencil_layer = layer;
|
||||
}
|
||||
|
||||
void draw_gpl_channel(AnimKeylistDrawList *draw_list,
|
||||
bDopeSheet *ads,
|
||||
bGPDlayer *gpl,
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
|
||||
#include "ED_anim_api.h"
|
||||
#include "ED_keyframes_keylist.h"
|
||||
@@ -54,6 +55,13 @@ BLI_INLINE bool is_cfra_lt(const float a, const float b)
|
||||
|
||||
/* --------------- */
|
||||
|
||||
/* Animation data of Grease Pencil cels,
|
||||
which are drawings positioned in time. */
|
||||
struct GreasePencilCel {
|
||||
int frame_number;
|
||||
GreasePencilFrame frame;
|
||||
};
|
||||
|
||||
struct AnimKeylist {
|
||||
/* Number of ActKeyColumn's in the keylist. */
|
||||
size_t column_len = 0;
|
||||
@@ -501,6 +509,47 @@ static void nupdate_ak_bezt(ActKeyColumn *ak, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
/* ......... */
|
||||
/* New node callback used for building ActKeyColumns from GPencil frames */
|
||||
static ActKeyColumn *nalloc_ak_cel(void *data)
|
||||
{
|
||||
ActKeyColumn *ak = static_cast<ActKeyColumn *>(
|
||||
MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnCel"));
|
||||
GreasePencilCel &cel = *static_cast<GreasePencilCel *>(data);
|
||||
|
||||
/* Store settings based on state of BezTriple */
|
||||
ak->cfra = cel.frame_number;
|
||||
ak->sel = (cel.frame.flag & SELECT) != 0;
|
||||
ak->key_type = cel.frame.type;
|
||||
|
||||
/* Count keyframes in this column */
|
||||
ak->totkey = 1;
|
||||
/* Set as visible block. */
|
||||
ak->totblock = 1;
|
||||
ak->block.sel = ak->sel;
|
||||
|
||||
return ak;
|
||||
}
|
||||
|
||||
/* Node updater callback used for building ActKeyColumns from GPencil frames */
|
||||
static void nupdate_ak_cel(ActKeyColumn *ak, void *data)
|
||||
{
|
||||
GreasePencilCel &cel = *static_cast<GreasePencilCel *>(data);
|
||||
|
||||
/* Update selection status */
|
||||
if (cel.frame.flag & GP_FRAME_SELECTED) {
|
||||
ak->sel = SELECT;
|
||||
}
|
||||
|
||||
/* Count keyframes in this column */
|
||||
ak->totkey++;
|
||||
|
||||
/* Update keytype status */
|
||||
if (cel.frame.type == BEZT_KEYTYPE_KEYFRAME) {
|
||||
ak->key_type = BEZT_KEYTYPE_KEYFRAME;
|
||||
}
|
||||
}
|
||||
|
||||
/* ......... */
|
||||
|
||||
/* New node callback used for building ActKeyColumns from GPencil frames */
|
||||
@@ -1110,6 +1159,24 @@ void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, AnimKeylist *keylist, con
|
||||
}
|
||||
}
|
||||
|
||||
void grease_pencil_cels_to_keylist(AnimData * /*adt*/,
|
||||
GreasePencilLayer *gpl,
|
||||
AnimKeylist *keylist,
|
||||
int /*saction_flag*/)
|
||||
{
|
||||
using namespace blender::bke::greasepencil;
|
||||
const Layer &layer = gpl->wrap();
|
||||
for (auto item : layer.frames().items()) {
|
||||
GreasePencilCel cel{};
|
||||
cel.frame_number = item.key;
|
||||
cel.frame = item.value;
|
||||
|
||||
float cfra = float(item.key);
|
||||
ED_keylist_add_or_update_column(
|
||||
keylist, cfra, nalloc_ak_cel, nupdate_ak_cel, static_cast<void *>(&cel));
|
||||
}
|
||||
}
|
||||
|
||||
void gpl_to_keylist(bDopeSheet * /*ads*/, bGPDlayer *gpl, AnimKeylist *keylist)
|
||||
{
|
||||
if (gpl && keylist) {
|
||||
|
||||
@@ -230,6 +230,9 @@ typedef enum eAnim_ChannelType {
|
||||
ANIMTYPE_GPDATABLOCK,
|
||||
ANIMTYPE_GPLAYER,
|
||||
|
||||
ANIMTYPE_GREASE_PENCIL_DATABLOCK,
|
||||
ANIMTYPE_GREASE_PENCIL_LAYER,
|
||||
|
||||
ANIMTYPE_MASKDATABLOCK,
|
||||
ANIMTYPE_MASKLAYER,
|
||||
|
||||
@@ -244,11 +247,12 @@ typedef enum eAnim_ChannelType {
|
||||
|
||||
/* types of keyframe data in bAnimListElem */
|
||||
typedef enum eAnim_KeyType {
|
||||
ALE_NONE = 0, /* no keyframe data */
|
||||
ALE_FCURVE, /* F-Curve */
|
||||
ALE_GPFRAME, /* Grease Pencil Frames */
|
||||
ALE_MASKLAY, /* Mask */
|
||||
ALE_NLASTRIP, /* NLA Strips */
|
||||
ALE_NONE = 0, /* no keyframe data */
|
||||
ALE_FCURVE, /* F-Curve */
|
||||
ALE_GPFRAME, /* Grease Pencil Frames (Legacy) */
|
||||
ALE_GREASE_PENCIL_CELS, /* Grease Pencil Cels */
|
||||
ALE_MASKLAY, /* Mask */
|
||||
ALE_NLASTRIP, /* NLA Strips */
|
||||
|
||||
ALE_ALL, /* All channels summary */
|
||||
ALE_SCE, /* Scene summary */
|
||||
|
||||
@@ -24,6 +24,7 @@ struct bActionGroup;
|
||||
struct bAnimContext;
|
||||
struct bDopeSheet;
|
||||
struct bGPDlayer;
|
||||
struct GreasePencilLayer;
|
||||
|
||||
/* draw simple diamond-shape keyframe */
|
||||
/* caller should set up vertex format, bind GPU_SHADER_KEYFRAME_SHAPE,
|
||||
@@ -91,6 +92,15 @@ void draw_summary_channel(struct AnimKeylistDrawList *draw_list,
|
||||
float ypos,
|
||||
float yscale_fac,
|
||||
int saction_flag);
|
||||
|
||||
/* Grease Pencil cels channels */
|
||||
void draw_grease_pencil_cels_channel(struct AnimKeylistDrawList *draw_list,
|
||||
struct bDopeSheet *ads,
|
||||
struct GreasePencilLayer *layer,
|
||||
float ypos,
|
||||
float yscale_fac,
|
||||
int saction_flag);
|
||||
|
||||
/* Grease Pencil Layer */
|
||||
void draw_gpl_channel(struct AnimKeylistDrawList *draw_list,
|
||||
struct bDopeSheet *ads,
|
||||
|
||||
@@ -23,6 +23,7 @@ struct Scene;
|
||||
struct bAnimContext;
|
||||
struct bDopeSheet;
|
||||
struct bGPDlayer;
|
||||
struct GreasePencilLayer;
|
||||
|
||||
/* ****************************** Base Structs ****************************** */
|
||||
|
||||
@@ -178,6 +179,13 @@ void gpencil_to_keylist(struct bDopeSheet *ads,
|
||||
struct bGPdata *gpd,
|
||||
struct AnimKeylist *keylist,
|
||||
bool active);
|
||||
|
||||
/* Grease Pencil Cels */
|
||||
void grease_pencil_cels_to_keylist(struct AnimData *adt,
|
||||
struct GreasePencilLayer *layer,
|
||||
struct AnimKeylist *keylist,
|
||||
int saction_flag);
|
||||
|
||||
/* Grease Pencil Layer */
|
||||
void gpl_to_keylist(struct bDopeSheet *ads, struct bGPDlayer *gpl, struct AnimKeylist *keylist);
|
||||
/* Mask */
|
||||
|
||||
@@ -458,6 +458,14 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region
|
||||
scale_factor,
|
||||
action_flag);
|
||||
break;
|
||||
case ALE_GREASE_PENCIL_CELS:
|
||||
draw_grease_pencil_cels_channel(draw_list,
|
||||
ads,
|
||||
static_cast<GreasePencilLayer *>(ale->data),
|
||||
ycenter,
|
||||
scale_factor,
|
||||
action_flag);
|
||||
break;
|
||||
case ALE_GPFRAME:
|
||||
draw_gpl_channel(draw_list,
|
||||
ads,
|
||||
|
||||
@@ -316,8 +316,7 @@ typedef struct GreasePencilLayerTreeGroup {
|
||||
* Flag for the grease pencil data-block. #GreasePencil.flag
|
||||
*/
|
||||
typedef enum GreasePencilFlag {
|
||||
/* TODO */
|
||||
GreasePencilFlag_TODO
|
||||
GREASE_PENCIL_ANIM_CHANNEL_EXPANDED = (1 << 0),
|
||||
} GreasePencilFlag;
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user