Compare commits
1 Commits
benchmark
...
tmp-Collec
Author | SHA1 | Date | |
---|---|---|---|
d1e3ba22a0 |
@@ -104,6 +104,7 @@ bool id_type_can_have_animdata(const short id_type)
|
||||
case ID_MSK:
|
||||
case ID_GD:
|
||||
case ID_CF:
|
||||
case ID_GR:
|
||||
return true;
|
||||
|
||||
/* no AnimData */
|
||||
@@ -1135,6 +1136,9 @@ void BKE_animdata_main_cb(Main *mainptr, ID_AnimData_Edit_Callback func, void *u
|
||||
/* masks */
|
||||
ANIMDATA_IDS_CB(mainptr->mask.first);
|
||||
|
||||
/* collections */
|
||||
ANIMDATA_IDS_CB(mainptr->collection.first);
|
||||
|
||||
/* worlds */
|
||||
ANIMDATA_NODETREE_IDS_CB(mainptr->world.first, World);
|
||||
|
||||
@@ -1234,6 +1238,9 @@ void BKE_animdata_fix_paths_rename_all(ID *ref_id, const char *prefix, const cha
|
||||
/* worlds */
|
||||
RENAMEFIX_ANIM_NODETREE_IDS(mainptr->world.first, World);
|
||||
|
||||
/* collections */
|
||||
RENAMEFIX_ANIM_IDS(mainptr->collection.first);
|
||||
|
||||
/* linestyles */
|
||||
RENAMEFIX_ANIM_IDS(mainptr->linestyle.first);
|
||||
|
||||
@@ -2935,6 +2942,9 @@ void BKE_animsys_evaluate_all_animation(Main *main, Depsgraph *depsgraph, Scene
|
||||
/* masks */
|
||||
EVAL_ANIM_IDS(main->mask.first, ADT_RECALC_ANIM);
|
||||
|
||||
/* collections */
|
||||
EVAL_ANIM_IDS(main->collection.first, ADT_RECALC_ANIM);
|
||||
|
||||
/* worlds */
|
||||
EVAL_ANIM_NODETREE_IDS(main->world.first, World, ADT_RECALC_ANIM);
|
||||
|
||||
|
@@ -35,6 +35,7 @@
|
||||
#include "BLT_translation.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_icons.h"
|
||||
#include "BKE_idprop.h"
|
||||
@@ -112,7 +113,8 @@ Collection *BKE_collection_add(Main *bmain, Collection *collection_parent, const
|
||||
/** Free (or release) any data used by this collection (does not free the collection itself). */
|
||||
void BKE_collection_free(Collection *collection)
|
||||
{
|
||||
/* No animdata here. */
|
||||
BKE_animdata_free(&collection->id, false);
|
||||
|
||||
BKE_previewimg_free(&collection->preview);
|
||||
|
||||
BLI_freelistN(&collection->gobject);
|
||||
|
@@ -5679,6 +5679,9 @@ static void direct_link_collection(FileData *fd, Collection *collection)
|
||||
link_list(fd, &collection->gobject);
|
||||
link_list(fd, &collection->children);
|
||||
|
||||
collection->adt = newdataadr(fd, collection->adt);
|
||||
direct_link_animdata(fd, collection->adt);
|
||||
|
||||
collection->preview = direct_link_preview_image(fd, collection->preview);
|
||||
|
||||
collection->flag &= ~COLLECTION_HAS_OBJECT_CACHE;
|
||||
@@ -5733,6 +5736,7 @@ static void lib_link_collection(FileData *fd, Main *main)
|
||||
if (collection->id.tag & LIB_TAG_NEED_LINK) {
|
||||
collection->id.tag &= ~LIB_TAG_NEED_LINK;
|
||||
IDP_LibLinkProperty(collection->id.properties, fd);
|
||||
lib_link_animdata(fd, &collection->id, collection->adt);
|
||||
|
||||
#ifdef USE_COLLECTION_COMPAT_28
|
||||
if (collection->collection) {
|
||||
@@ -9272,6 +9276,10 @@ static void expand_particlesettings(FileData *fd, Main *mainvar, ParticleSetting
|
||||
|
||||
static void expand_collection(FileData *fd, Main *mainvar, Collection *collection)
|
||||
{
|
||||
if (collection->adt) {
|
||||
expand_animdata(fd, mainvar, collection->adt);
|
||||
}
|
||||
|
||||
for (CollectionObject *cob = collection->gobject.first; cob; cob = cob->next) {
|
||||
expand_doit(fd, mainvar, cob->ob);
|
||||
}
|
||||
|
@@ -2376,6 +2376,10 @@ static void write_collection(WriteData *wd, Collection *collection)
|
||||
/* write LibData */
|
||||
writestruct(wd, ID_GR, Collection, 1, collection);
|
||||
write_iddata(wd, &collection->id);
|
||||
|
||||
if (collection->adt) {
|
||||
write_animdata(wd, collection->adt);
|
||||
}
|
||||
|
||||
write_collection_nolib(wd, collection);
|
||||
}
|
||||
|
@@ -435,6 +435,8 @@ void DepsgraphNodeBuilder::build_collection(Collection *collection)
|
||||
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
|
||||
build_collection(child->collection);
|
||||
}
|
||||
/* Build animation data. */
|
||||
build_animdata(&collection->id);
|
||||
|
||||
add_id_node(&collection->id);
|
||||
}
|
||||
|
@@ -444,6 +444,8 @@ void DepsgraphRelationBuilder::build_collection(Object *object, Collection *coll
|
||||
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
|
||||
build_collection(NULL, child->collection);
|
||||
}
|
||||
/* Animation data - should only need one set of relations per collection, not once per instance */
|
||||
build_animdata(&collection->id);
|
||||
}
|
||||
if (object != NULL) {
|
||||
const ListBase group_objects = BKE_collection_object_cache_get(collection);
|
||||
|
@@ -626,6 +626,111 @@ static bAnimChannelType ACF_SCENE =
|
||||
acf_scene_setting_ptr /* pointer for setting */
|
||||
};
|
||||
|
||||
/* Collection ------------------------------------------- */
|
||||
|
||||
// TODO: just get this from RNA?
|
||||
static int acf_collection_icon(bAnimListElem *UNUSED(ale))
|
||||
{
|
||||
return ICON_GROUP;
|
||||
}
|
||||
|
||||
/* check if some setting exists for this channel */
|
||||
static bool acf_collection_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
|
||||
{
|
||||
switch (setting) {
|
||||
/* muted only in NLA */
|
||||
case ACHANNEL_SETTING_MUTE:
|
||||
return ((ac) && (ac->spacetype == SPACE_NLA));
|
||||
|
||||
/* visible only in Graph Editor */
|
||||
case ACHANNEL_SETTING_VISIBLE:
|
||||
return ((ac) && (ac->spacetype == SPACE_IPO));
|
||||
|
||||
/* only select and expand supported otherwise */
|
||||
case ACHANNEL_SETTING_SELECT:
|
||||
case ACHANNEL_SETTING_EXPAND:
|
||||
return true;
|
||||
|
||||
case ACHANNEL_SETTING_ALWAYS_VISIBLE:
|
||||
return false;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* get the appropriate flag(s) for the setting when it is valid */
|
||||
static int acf_collection_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
|
||||
{
|
||||
/* clear extra return data first */
|
||||
*neg = false;
|
||||
|
||||
switch (setting) {
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
return COLLECTION_DS_SELECTED;
|
||||
|
||||
case ACHANNEL_SETTING_EXPAND: /* expanded */
|
||||
*neg = true;
|
||||
return COLLECTION_DS_COLLAPSED;
|
||||
|
||||
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
|
||||
return ADT_NLA_EVAL_OFF;
|
||||
|
||||
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
|
||||
*neg = true;
|
||||
return ADT_CURVES_NOT_VISIBLE;
|
||||
|
||||
default: /* unsupported */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* get pointer to the setting */
|
||||
static void *acf_collection_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
|
||||
{
|
||||
Collection *collection = (Collection *)ale->data;
|
||||
|
||||
/* clear extra return data first */
|
||||
*type = 0;
|
||||
|
||||
switch (setting) {
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
return GET_ACF_FLAG_PTR(collection->flag, type);
|
||||
|
||||
case ACHANNEL_SETTING_EXPAND: /* expanded */
|
||||
return GET_ACF_FLAG_PTR(collection->flag, type);
|
||||
|
||||
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
|
||||
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
|
||||
if (collection->adt)
|
||||
return GET_ACF_FLAG_PTR(collection->adt->flag, type);
|
||||
return NULL;
|
||||
|
||||
default: /* unsupported */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* collection type define */
|
||||
static bAnimChannelType ACF_COLLECTION =
|
||||
{
|
||||
"Collection", /* type name */
|
||||
ACHANNEL_ROLE_EXPANDER, /* role */
|
||||
|
||||
acf_generic_root_color, /* backdrop color */
|
||||
acf_generic_root_backdrop, /* backdrop */
|
||||
acf_generic_indention_0, /* indent level */
|
||||
NULL, /* offset */
|
||||
|
||||
acf_generic_idblock_name, /* name */
|
||||
acf_generic_idblock_name_prop, /* name prop */
|
||||
acf_collection_icon, /* icon */
|
||||
|
||||
acf_collection_setting_valid, /* has setting */
|
||||
acf_collection_setting_flag, /* flag for setting */
|
||||
acf_collection_setting_ptr /* pointer for setting */
|
||||
};
|
||||
|
||||
/* Object ------------------------------------------- */
|
||||
|
||||
static int acf_object_icon(bAnimListElem *ale)
|
||||
@@ -3567,8 +3672,9 @@ static void ANIM_init_channel_typeinfo_data(void)
|
||||
animchannelTypeInfo[type++] = &ACF_SUMMARY; /* Motion Summary */
|
||||
|
||||
animchannelTypeInfo[type++] = &ACF_SCENE; /* Scene */
|
||||
animchannelTypeInfo[type++] = &ACF_COLLECTION; /* Collection */
|
||||
animchannelTypeInfo[type++] = &ACF_OBJECT; /* Object */
|
||||
animchannelTypeInfo[type++] = &ACF_GROUP; /* Group */
|
||||
animchannelTypeInfo[type++] = &ACF_GROUP; /* ActionGroup */
|
||||
animchannelTypeInfo[type++] = &ACF_FCURVE; /* F-Curve */
|
||||
|
||||
animchannelTypeInfo[type++] = &ACF_NLACONTROLS; /* NLA Control FCurve Expander */
|
||||
|
@@ -280,6 +280,10 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d
|
||||
if (ale->flag & SCE_DS_SELECTED)
|
||||
sel = ACHANNEL_SETFLAG_CLEAR;
|
||||
break;
|
||||
case ANIMTYPE_COLLECTION:
|
||||
if (ale->flag & COLLECTION_DS_SELECTED)
|
||||
sel = ACHANNEL_SETFLAG_CLEAR;
|
||||
break;
|
||||
case ANIMTYPE_OBJECT:
|
||||
#if 0 /* for now, do not take object selection into account, since it gets too annoying */
|
||||
if (ale->flag & SELECT)
|
||||
@@ -354,6 +358,17 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_COLLECTION:
|
||||
{
|
||||
Collection *collection = (Collection *)ale->data;
|
||||
|
||||
ACHANNEL_SET_FLAG(collection, sel, COLLECTION_DS_SELECTED);
|
||||
|
||||
if (collection->adt) {
|
||||
ACHANNEL_SET_FLAG(collection, sel, ADT_UI_SELECTED);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_OBJECT:
|
||||
{
|
||||
#if 0 /* for now, do not take object selection into account, since it gets too annoying */
|
||||
@@ -2681,6 +2696,25 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
|
||||
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_COLLECTION:
|
||||
{
|
||||
Collection *collection = (Collection *)ale->data;
|
||||
AnimData *adt = collection->adt;
|
||||
|
||||
/* set selection status */
|
||||
if (selectmode == SELECT_INVERT) {
|
||||
/* swap select */
|
||||
collection->flag ^= COLLECTION_DS_SELECTED;
|
||||
if (adt) adt->flag ^= ADT_UI_SELECTED;
|
||||
}
|
||||
else {
|
||||
collection->flag |= COLLECTION_DS_SELECTED;
|
||||
if (adt) adt->flag |= ADT_UI_SELECTED;
|
||||
}
|
||||
|
||||
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_OBJECT:
|
||||
{
|
||||
#if 0
|
||||
|
@@ -614,6 +614,19 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
|
||||
ale->adt = BKE_animdata_from_id(data);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_COLLECTION:
|
||||
{
|
||||
Collection *collection = (Collection *)data;
|
||||
|
||||
ale->flag = collection->flag;
|
||||
|
||||
/* XXX: Nothing to include here for now... to be populated later */
|
||||
ale->key_data = NULL;
|
||||
ale->datatype = ALE_NONE;
|
||||
|
||||
ale->adt = BKE_animdata_from_id(data);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_OBJECT:
|
||||
{
|
||||
Base *base = (Base *)data;
|
||||
@@ -2630,6 +2643,102 @@ static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data
|
||||
return items;
|
||||
}
|
||||
|
||||
/* animation channels for collection */
|
||||
static size_t animdata_filter_ds_collection(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Collection *collection, int filter_mode)
|
||||
{
|
||||
ListBase tmp_data = {NULL, NULL};
|
||||
size_t tmp_items = 0;
|
||||
size_t items = 0;
|
||||
|
||||
AnimData *adt = collection->adt;
|
||||
short type = 0, expanded = 1;
|
||||
void *cdata = NULL;
|
||||
|
||||
/* determine the type of expander channels to use */
|
||||
// this is the best way to do this for now...
|
||||
ANIMDATA_FILTER_CASES(collection,
|
||||
{ /* AnimData - no channel, but consider data */},
|
||||
{ /* NLA - no channel, but consider data */},
|
||||
{ /* Drivers */
|
||||
type = ANIMTYPE_FILLDRIVERS;
|
||||
cdata = adt;
|
||||
expanded = EXPANDED_DRVD(adt);
|
||||
},
|
||||
{ /* NLA Strip Controls - no dedicated channel for now (XXX) */ },
|
||||
{ /* Keyframes */
|
||||
type = ANIMTYPE_FILLACTD;
|
||||
cdata = adt->action;
|
||||
expanded = EXPANDED_ACTC(adt->action);
|
||||
});
|
||||
|
||||
/* add scene-level animation channels */
|
||||
BEGIN_ANIMFILTER_SUBCHANNELS(expanded)
|
||||
{
|
||||
/* animation data filtering */
|
||||
tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)collection, filter_mode);
|
||||
}
|
||||
END_ANIMFILTER_SUBCHANNELS;
|
||||
|
||||
/* did we find anything? */
|
||||
if (tmp_items) {
|
||||
/* include anim-expand widget first */
|
||||
if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
|
||||
if (type != ANIMTYPE_NONE) {
|
||||
/* NOTE: active-status (and the associated checks) don't apply here... */
|
||||
ANIMCHANNEL_NEW_CHANNEL(cdata, type, collection);
|
||||
}
|
||||
}
|
||||
|
||||
/* now add the list of collected channels */
|
||||
BLI_movelisttolist(anim_data, &tmp_data);
|
||||
BLI_assert(BLI_listbase_is_empty(&tmp_data));
|
||||
items += tmp_items;
|
||||
}
|
||||
|
||||
/* return the number of items added to the list */
|
||||
return items;
|
||||
}
|
||||
|
||||
/* collection animation */
|
||||
static size_t animdata_filter_dopesheet_collection(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Collection *collection, int filter_mode)
|
||||
{
|
||||
ListBase tmp_data = {NULL, NULL};
|
||||
size_t tmp_items = 0;
|
||||
size_t items = 0;
|
||||
|
||||
/* filter data contained under collection first */
|
||||
BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_COLLECTIONC(collection))
|
||||
{
|
||||
/* Action, Drivers, or NLA for Collection itself */
|
||||
//if ((ads->filterflag & ADS_FILTER_NOSCE) == 0) {
|
||||
tmp_items += animdata_filter_ds_collection(ac, &tmp_data, ads, collection, filter_mode);
|
||||
//}
|
||||
|
||||
/* TODO: Allow showing for stuff inside collection? */
|
||||
}
|
||||
END_ANIMFILTER_SUBCHANNELS;
|
||||
|
||||
/* if we collected some channels, add these to the new list... */
|
||||
if (tmp_items) {
|
||||
/* firstly add object expander if required */
|
||||
if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
|
||||
/* check if filtering by selection */
|
||||
if (ANIMCHANNEL_SELOK((collection->flag & COLLECTION_DS_SELECTED))) {
|
||||
/* NOTE: active-status doesn't matter for this! */
|
||||
ANIMCHANNEL_NEW_CHANNEL(collection, ANIMTYPE_COLLECTION, collection);
|
||||
}
|
||||
}
|
||||
|
||||
/* now add the list of collected channels */
|
||||
BLI_movelisttolist(anim_data, &tmp_data);
|
||||
BLI_assert(BLI_listbase_is_empty(&tmp_data));
|
||||
items += tmp_items;
|
||||
}
|
||||
|
||||
/* return the number of items added */
|
||||
return items;
|
||||
}
|
||||
|
||||
static size_t animdata_filter_ds_world(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, World *wo, int filter_mode)
|
||||
{
|
||||
ListBase tmp_data = {NULL, NULL};
|
||||
@@ -2729,7 +2838,7 @@ static size_t animdata_filter_dopesheet_scene(bAnimContext *ac, ListBase *anim_d
|
||||
size_t tmp_items = 0;
|
||||
size_t items = 0;
|
||||
|
||||
/* filter data contained under object first */
|
||||
/* filter data contained under scene first */
|
||||
BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_SCEC(sce))
|
||||
{
|
||||
bNodeTree *ntree = sce->nodetree;
|
||||
@@ -2969,7 +3078,13 @@ static size_t animdata_filter_dopesheet(bAnimContext *ac, ListBase *anim_data, b
|
||||
|
||||
/* scene-linked animation - e.g. world, compositing nodes, scene anim (including sequencer currently) */
|
||||
items += animdata_filter_dopesheet_scene(ac, anim_data, ads, scene, filter_mode);
|
||||
|
||||
|
||||
/* collection animation */
|
||||
/* XXX: Just list all collections for now */
|
||||
for (Collection *collection = G.main->collection.first; collection; collection = collection->id.next) {
|
||||
items += animdata_filter_dopesheet_collection(ac, anim_data, ads, collection, filter_mode);
|
||||
}
|
||||
|
||||
/* If filtering for channel drawing, we want the objects in alphabetical order,
|
||||
* to make it easier to predict where items are in the hierarchy
|
||||
* - This order only really matters if we need to show all channels in the list (e.g. for drawing)
|
||||
@@ -3074,6 +3189,10 @@ static size_t animdata_filter_animchan(bAnimContext *ac, ListBase *anim_data, bD
|
||||
case ANIMTYPE_SCENE:
|
||||
items += animdata_filter_dopesheet_scene(ac, anim_data, ads, channel->data, filter_mode);
|
||||
break;
|
||||
|
||||
case ANIMTYPE_COLLECTION:
|
||||
items += animdata_filter_dopesheet_collection(ac, anim_data, ads, channel->data, filter_mode);
|
||||
break;
|
||||
|
||||
case ANIMTYPE_OBJECT:
|
||||
items += animdata_filter_dopesheet_ob(ac, anim_data, ads, channel->data, filter_mode);
|
||||
|
@@ -155,6 +155,7 @@ typedef enum eAnim_ChannelType {
|
||||
ANIMTYPE_SUMMARY,
|
||||
|
||||
ANIMTYPE_SCENE,
|
||||
ANIMTYPE_COLLECTION,
|
||||
ANIMTYPE_OBJECT,
|
||||
ANIMTYPE_GROUP,
|
||||
ANIMTYPE_FCURVE,
|
||||
@@ -281,6 +282,9 @@ typedef enum eAnimFilter_Flags {
|
||||
/* 'Sub-Scene' channels (flags stored in Data block) */
|
||||
#define FILTER_WOR_SCED(wo) (CHECK_TYPE_INLINE(wo, World *), (wo->flag & WO_DS_EXPAND))
|
||||
#define FILTER_LS_SCED(linestyle) ((linestyle->flag & LS_DS_EXPAND))
|
||||
/* 'Collection' channels */
|
||||
#define SEL_COLLECTIONC(collection) (CHECK_TYPE_INLINE(collection, Collection *), ((collection->flag & COLLECTION_DS_SELECTED)))
|
||||
#define EXPANDED_COLLECTIONC(collection) (CHECK_TYPE_INLINE(collection, Collection *), ((collection->flag & COLLECTION_DS_COLLAPSED) == 0))
|
||||
/* 'Object' channels */
|
||||
#define SEL_OBJC(base) (CHECK_TYPE_INLINE(base, Base *), ((base->flag & SELECT)))
|
||||
#define EXPANDED_OBJC(ob) (CHECK_TYPE_INLINE(ob, Object *), ((ob->nlaflag & OB_ADS_COLLAPSED) == 0))
|
||||
|
@@ -243,6 +243,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *ar)
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_SCENE:
|
||||
case ANIMTYPE_COLLECTION:
|
||||
case ANIMTYPE_OBJECT:
|
||||
{
|
||||
immUniformColor3ubvAlpha(col1b, sel ? 0x45 : 0x22);
|
||||
|
@@ -127,6 +127,7 @@ bool nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA *nlt_p
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_SCENE: /* Top-Level Widgets doubling up as datablocks */
|
||||
case ANIMTYPE_COLLECTION:
|
||||
case ANIMTYPE_OBJECT:
|
||||
case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
|
||||
case ANIMTYPE_DSLAM:
|
||||
|
@@ -122,6 +122,25 @@ static int mouse_nla_channels(bContext *C, bAnimContext *ac, float x, int channe
|
||||
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_COLLECTION:
|
||||
{
|
||||
Collection *collection = (Collection *)ale->data;
|
||||
AnimData *adt = collection->adt;
|
||||
|
||||
/* set selection status */
|
||||
if (selectmode == SELECT_INVERT) {
|
||||
/* swap select */
|
||||
collection->flag ^= COLLECTION_DS_SELECTED;
|
||||
if (adt) adt->flag ^= ADT_UI_SELECTED;
|
||||
}
|
||||
else {
|
||||
collection->flag |= COLLECTION_DS_SELECTED;
|
||||
if (adt) adt->flag |= ADT_UI_SELECTED;
|
||||
}
|
||||
|
||||
notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_OBJECT:
|
||||
{
|
||||
ViewLayer *view_layer = ac->view_layer;
|
||||
|
@@ -40,6 +40,7 @@
|
||||
|
||||
struct Object;
|
||||
struct Collection;
|
||||
struct AnimData;
|
||||
|
||||
typedef struct CollectionObject {
|
||||
struct CollectionObject *next, *prev;
|
||||
@@ -55,6 +56,7 @@ typedef struct CollectionChild {
|
||||
|
||||
typedef struct Collection {
|
||||
ID id;
|
||||
struct AnimData *adt;
|
||||
|
||||
ListBase gobject; /* CollectionObject */
|
||||
ListBase children; /* CollectionChild */
|
||||
@@ -89,6 +91,9 @@ enum {
|
||||
COLLECTION_RESTRICT_RENDER = (1 << 3), /* Hidden in renders. */
|
||||
COLLECTION_HAS_OBJECT_CACHE = (1 << 4), /* Runtime: object_cache is populated. */
|
||||
COLLECTION_IS_MASTER = (1 << 5), /* Is master collection embedded in the scene. */
|
||||
|
||||
COLLECTION_DS_SELECTED = (1 << 10), /* Channel is selected in animation editors */
|
||||
COLLECTION_DS_COLLAPSED = (1 << 11), /* Channel is collapsed in animation editors (defaults open) */
|
||||
};
|
||||
|
||||
#endif /* __DNA_GROUP_TYPES_H__ */
|
||||
|
@@ -275,6 +275,9 @@ void RNA_def_collections(BlenderRNA *brna)
|
||||
RNA_def_property_ui_icon(prop, ICON_RESTRICT_RENDER_OFF, 1);
|
||||
RNA_def_property_ui_text(prop, "Restrict Render", "Hide collection objects in renders");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_Collection_flag_update");
|
||||
|
||||
/* Animation Data */
|
||||
rna_def_animdata_common(srna);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user