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:
-rw-r--r--source/blender/blenkernel/BKE_key.h1
-rw-r--r--source/blender/blenkernel/intern/key.c25
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c198
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c32
-rw-r--r--source/blender/editors/animation/anim_filter.c82
-rw-r--r--source/blender/editors/include/ED_anim_api.h10
-rw-r--r--source/blender/makesdna/DNA_key_types.h6
7 files changed, 314 insertions, 40 deletions
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index 4bfa6a41099..1b4cbc1cf2a 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -65,6 +65,7 @@ struct Key *ob_get_key(struct Object *ob);
struct KeyBlock *ob_get_keyblock(struct Object *ob);
struct KeyBlock *key_get_keyblock(struct Key *key, int index);
struct KeyBlock *key_get_named_keyblock(struct Key *key, const char name[]);
+char *key_get_curValue_rnaPath(struct Key *key, struct KeyBlock *kb);
// needed for the GE
void do_rel_key(int start, int end, int tot, char *basispoin, struct Key *key, int mode);
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index b6e4ffd6cc3..3fffdef478b 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -35,6 +35,8 @@
#include "MEM_guardedalloc.h"
+#include "BLI_blenlib.h"
+
#include "DNA_anim_types.h"
#include "DNA_curve_types.h"
#include "DNA_key_types.h"
@@ -57,7 +59,7 @@
#include "BKE_object.h"
#include "BKE_utildefines.h"
-#include "BLI_blenlib.h"
+#include "RNA_access.h"
#ifdef HAVE_CONFIG_H
@@ -1489,3 +1491,24 @@ KeyBlock *key_get_named_keyblock(Key *key, const char name[])
return NULL;
}
+
+/* Get RNA-Path for 'value' setting of the given ShapeKey
+ * NOTE: the user needs to free the returned string once they're finishe with it
+ */
+char *key_get_curValue_rnaPath(Key *key, KeyBlock *kb)
+{
+ PointerRNA ptr;
+ PropertyRNA *prop;
+
+ /* sanity checks */
+ if ELEM(NULL, key, kb)
+ return NULL;
+
+ /* create the RNA pointer */
+ RNA_pointer_create(key, &RNA_ShapeKey, kb, &ptr);
+ /* get pointer to the property too */
+ prop= RNA_struct_find_property(&ptr, "value");
+
+ /* return the path */
+ return RNA_path_from_ID_to_property(&ptr, prop);
+}
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index 7c9814eda7b..2cd41b0ffb7 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -1386,7 +1386,7 @@ static int acf_dsskey_setting_flag(int setting, short *neg)
switch (setting) {
case ACHANNEL_SETTING_EXPAND: /* expanded */
- return KEYBLOCK_DS_EXPAND;
+ return KEY_DS_EXPAND;
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
return ADT_NLA_EVAL_OFF;
@@ -1737,28 +1737,91 @@ static bAnimChannelType ACF_DSARM=
/* ShapeKey Entry ------------------------------------------- */
-// XXX ... this is currently obsolete...
-#if 0
-static void dummy_olddraw_shapekeys ()
+/* name for ShapeKey */
+static void acf_shapekey_name(bAnimListElem *ale, char *name)
{
- case ANIMTYPE_SHAPEKEY: /* shapekey channel */
- {
- KeyBlock *kb = (KeyBlock *)ale->data;
+ KeyBlock *kb= (KeyBlock *)ale->data;
+
+ /* just copy the name... */
+ if (kb && name) {
+ /* if the KeyBlock had a name, use it, otherwise use the index */
+ if (kb->name[0])
+ strcpy(name, kb->name);
+ else
+ sprintf(name, "Key %d", ale->index);
+ }
+}
+
+/* check if some setting exists for this channel */
+static short acf_shapekey_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
+{
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted */
+ case ACHANNEL_SETTING_PROTECT: /* protected */
+ return 1;
+
+ /* nothing else is supported */
+ default:
+ return 0;
+ }
+}
+
+/* get the appropriate flag(s) for the setting when it is valid */
+static int acf_shapekey_setting_flag(int setting, short *neg)
+{
+ /* clear extra return data first */
+ *neg= 0;
+
+ switch (setting) {
+ case ACHANNEL_SETTING_MUTE: /* mute */
+ return KEYBLOCK_MUTE;
- indent = 0;
- special = -1;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return KEYBLOCK_SEL;
- offset= (ale->id) ? 21 : 0;
+ case ACHANNEL_SETTING_PROTECT: /* locked */
+ return KEYBLOCK_LOCKED;
- if (kb->name[0] == '\0')
- sprintf(name, "Key %d", ale->index);
- else
- strcpy(name, kb->name);
+ default: /* unsupported */
+ return 0;
}
- break;
}
-#endif
+
+/* get pointer to the setting */
+static void *acf_shapekey_setting_ptr(bAnimListElem *ale, int setting, short *type)
+{
+ KeyBlock *kb= (KeyBlock *)ale->data;
+
+ /* clear extra return data first */
+ *type= 0;
+
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted */
+ case ACHANNEL_SETTING_PROTECT: /* protected */
+ GET_ACF_FLAG_PTR(kb->flag)
+
+ default: /* unsupported */
+ return NULL;
+ }
+}
+
+/* shapekey expander type define */
+static bAnimChannelType ACF_SHAPEKEY=
+{
+ acf_generic_channel_backdrop, /* backdrop */
+ acf_generic_indention_0, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_shapekey_name, /* name */
+ NULL, /* icon */
+
+ acf_shapekey_setting_valid, /* has setting */
+ acf_shapekey_setting_flag, /* flag for setting */
+ acf_shapekey_setting_ptr /* pointer for setting */
+};
/* Grease Pencil entries ------------------------------------------- */
// XXX ... this is currently not restored yet
@@ -1923,7 +1986,7 @@ void ANIM_init_channel_typeinfo_data (void)
animchannelTypeInfo[type++]= &ACF_DSMBALL; /* MetaBall Channel */
animchannelTypeInfo[type++]= &ACF_DSARM; /* Armature Channel */
- animchannelTypeInfo[type++]= NULL; /* ShapeKey */ // XXX this is no longer used for now...
+ animchannelTypeInfo[type++]= &ACF_SHAPEKEY; /* ShapeKey */
// XXX not restored yet
animchannelTypeInfo[type++]= NULL; /* Grease Pencil Datablock */
@@ -2237,7 +2300,57 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
}
}
-
+/* callback for shapekey widget sliders - insert keyframes */
+static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, void *kb_poin)
+{
+ Key *key= (Key *)key_poin;
+ KeyBlock *kb= (KeyBlock *)kb_poin;
+ char *rna_path= key_get_curValue_rnaPath(key, kb);
+
+ Scene *scene= CTX_data_scene(C);
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+ short flag=0, done=0;
+ float cfra;
+
+ /* get current frame */
+ // NOTE: this will do for now...
+ cfra= (float)CFRA;
+
+ /* get flags for keyframing */
+ if (IS_AUTOKEY_FLAG(INSERTNEEDED))
+ flag |= INSERTKEY_NEEDED;
+ if (IS_AUTOKEY_FLAG(AUTOMATKEY))
+ flag |= INSERTKEY_MATRIX;
+ if (IS_AUTOKEY_MODE(scene, EDITKEYS))
+ flag |= INSERTKEY_REPLACE;
+
+
+ /* get RNA pointer, and resolve the path */
+ RNA_id_pointer_create((ID *)key, &id_ptr);
+
+ /* try to resolve the path stored in the F-Curve */
+ if (RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop)) {
+ /* find or create new F-Curve */
+ // XXX is the group name for this ok?
+ bAction *act= verify_adt_action((ID *)key, 1);
+ FCurve *fcu= verify_fcurve(act, NULL, rna_path, 0, 1);
+
+ /* set the special 'replace' flag if on a keyframe */
+ if (fcurve_frame_has_keyframe(fcu, cfra, 0))
+ flag |= INSERTKEY_REPLACE;
+
+ /* insert a keyframe for this F-Curve */
+ done= insert_keyframe_direct(ptr, prop, fcu, cfra, flag);
+
+ if (done)
+ WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL);
+ }
+
+ /* free the path */
+ if (rna_path)
+ MEM_freeN(rna_path);
+}
/* Draw a widget for some setting */
static void draw_setting_widget (bAnimContext *ac, bAnimListElem *ale, bAnimChannelType *acf, uiBlock *block, int xpos, int ypos, int setting)
@@ -2445,7 +2558,7 @@ void ANIM_channel_draw_widgets (bAnimContext *ac, bAnimListElem *ale, uiBlock *b
* and wouldn't be able to auto-keyframe...
* - slider should start before the toggles (if they're visible) to keep a clean line down the side
*/
- if ((draw_sliders) && (ale->type == ANIMTYPE_FCURVE)) {
+ if ((draw_sliders) && ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_SHAPEKEY)) {
/* adjust offset */
offset += SLIDER_WIDTH;
@@ -2453,20 +2566,49 @@ void ANIM_channel_draw_widgets (bAnimContext *ac, bAnimListElem *ale, uiBlock *b
uiBlockSetEmboss(block, UI_EMBOSS);
if (ale->id) { /* Slider using RNA Access -------------------- */
- FCurve *fcu= (FCurve *)ale->data;
PointerRNA id_ptr, ptr;
PropertyRNA *prop;
+ char *rna_path = NULL;
+ int array_index = 0;
+ short free_path = 0;
- /* get RNA pointer, and resolve the path */
- RNA_id_pointer_create(ale->id, &id_ptr);
+ /* get destination info */
+ if (ale->type == ANIMTYPE_FCURVE) {
+ FCurve *fcu= (FCurve *)ale->data;
+
+ rna_path= fcu->rna_path;
+ array_index= fcu->array_index;
+ }
+ else if (ale->type == ANIMTYPE_SHAPEKEY) {
+ KeyBlock *kb= (KeyBlock *)ale->data;
+ Key *key= (Key *)ale->id;
+
+ rna_path= key_get_curValue_rnaPath(key, kb);
+ free_path= 1;
+ }
- /* try to resolve the path */
- if (RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) {
- uiBut *but;
+ /* only if RNA-Path found */
+ if (rna_path) {
+ /* get RNA pointer, and resolve the path */
+ RNA_id_pointer_create(ale->id, &id_ptr);
+
+ /* try to resolve the path */
+ if (RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop)) {
+ uiBut *but;
+
+ /* create the slider button, and assign relevant callback to ensure keyframes are inserted... */
+ but= uiDefAutoButR(block, &ptr, prop, array_index, "", 0, (int)v2d->cur.xmax-offset, ymid, SLIDER_WIDTH, (int)ymaxc-yminc);
+
+ /* assign keyframing function according to slider type */
+ if (ale->type == ANIMTYPE_SHAPEKEY)
+ uiButSetFunc(but, achannel_setting_slider_shapekey_cb, ale->id, ale->data);
+ else
+ uiButSetFunc(but, achannel_setting_slider_cb, ale->id, ale->data);
+ }
- /* create the slider button, and assign relevant callback to ensure keyframes are inserted... */
- but= uiDefAutoButR(block, &ptr, prop, fcu->array_index, "", 0, (int)v2d->cur.xmax-offset, ymid, SLIDER_WIDTH, (int)ymaxc-yminc);
- uiButSetFunc(but, achannel_setting_slider_cb, ale->id, fcu);
+ /* free the path if necessary */
+ if (free_path)
+ MEM_freeN(rna_path);
}
}
else { /* Special Slider for stuff without RNA Access ---------- */
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 3b6c7fad471..efdad53f89f 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -238,6 +238,10 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
if (ale->flag & FCURVE_SELECTED)
sel= ACHANNEL_SETFLAG_CLEAR;
break;
+ case ANIMTYPE_SHAPEKEY:
+ if (ale->flag & KEYBLOCK_SEL)
+ sel= ACHANNEL_SETFLAG_CLEAR;
+ break;
case ANIMTYPE_NLATRACK:
if (ale->flag & NLATRACK_SELECTED)
sel= ACHANNEL_SETFLAG_CLEAR;
@@ -307,6 +311,13 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
fcu->flag &= ~FCURVE_ACTIVE;
}
break;
+ case ANIMTYPE_SHAPEKEY:
+ {
+ KeyBlock *kb= (KeyBlock *)ale->data;
+
+ ACHANNEL_SET_FLAG(kb, sel, KEYBLOCK_SEL);
+ }
+ break;
case ANIMTYPE_NLATRACK:
{
NlaTrack *nlt= (NlaTrack *)ale->data;
@@ -1520,6 +1531,24 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh
notifierFlags |= ND_ANIMCHAN_SELECT;
}
break;
+ case ANIMTYPE_SHAPEKEY:
+ {
+ KeyBlock *kb= (KeyBlock *)ale->data;
+
+ /* select/deselect */
+ if (selectmode == SELECT_INVERT) {
+ /* inverse selection status of this ShapeKey only */
+ kb->flag ^= KEYBLOCK_SEL;
+ }
+ else {
+ /* select ShapeKey by itself */
+ ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
+ kb->flag |= KEYBLOCK_SEL;
+ }
+
+ notifierFlags |= ND_ANIMCHAN_SELECT;
+ }
+ break;
case ANIMTYPE_GPDATABLOCK:
{
bGPdata *gpd= (bGPdata *)ale->data;
@@ -1557,9 +1586,6 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh
#endif // XXX future of this is unclear
}
break;
- case ANIMTYPE_SHAPEKEY:
- /* TODO: shapekey channels cannot be selected atm... */
- break;
default:
printf("Error: Invalid channel type in mouse_anim_channels() \n");
}
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index ea097420d1a..84da3662661 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -647,6 +647,36 @@ bAnimListElem *make_new_animlistelem (void *data, short datatype, void *owner, s
ale->datatype= ALE_FCURVE;
}
break;
+
+ case ANIMTYPE_SHAPEKEY:
+ {
+ KeyBlock *kb= (KeyBlock *)data;
+ Key *key= (Key *)ale->id;
+
+ ale->flag= kb->flag;
+
+ /* whether we have keyframes depends on whether there is a Key block to find it from */
+ if (key) {
+ /* index of shapekey is defined by place in key's list */
+ ale->index= BLI_findindex(&key->block, kb);
+
+ /* the corresponding keyframes are from the animdata */
+ if (ale->adt && ale->adt->action) {
+ bAction *act= ale->adt->action;
+ char *rna_path = key_get_curValue_rnaPath(key, kb);
+
+ /* try to find the F-Curve which corresponds to this exactly,
+ * then free the MEM_alloc'd string
+ */
+ if (rna_path) {
+ ale->key_data= list_find_fcurve(&act->curves, rna_path, 0);
+ MEM_freeN(rna_path);
+ }
+ }
+ ale->datatype= (ale->key_data)? ALE_FCURVE : ALE_NONE;
+ }
+ }
+ break;
case ANIMTYPE_GPLAYER:
{
@@ -892,7 +922,51 @@ static int animdata_filter_nla (ListBase *anim_data, bDopeSheet *ads, AnimData *
/* return the number of items added to the list */
return items;
}
-
+
+/* Include ShapeKey Data for ShapeKey Editor */
+static int animdata_filter_shapekey (ListBase *anim_data, Key *key, int filter_mode)
+{
+ int items = 0;
+
+ /* check if channels or only F-Curves */
+ if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) {
+ bAnimListElem *ale;
+ KeyBlock *kb;
+
+ /* loop through the channels adding ShapeKeys as appropriate */
+ for (kb= key->block.first; kb; kb= kb->next) {
+ /* skip the first one, since that's the non-animateable basis */
+ // XXX maybe in future this may become handy?
+ if (kb == key->block.first) continue;
+
+ /* only work with this channel and its subchannels if it is editable */
+ if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_SHAPEKEY(kb)) {
+ /* only include this track if selected in a way consistent with the filtering requirements */
+ if ( ANIMCHANNEL_SELOK(SEL_SHAPEKEY(kb)) ) {
+ // TODO: consider 'active' too?
+
+ /* owner-id here must be key so that the F-Curve can be resolved... */
+ ale= make_new_animlistelem(kb, ANIMTYPE_SHAPEKEY, NULL, ANIMTYPE_NONE, (ID *)key);
+
+ if (ale) {
+ BLI_addtail(anim_data, ale);
+ items++;
+ }
+ }
+ }
+ }
+ }
+ else {
+ /* just use the action associated with the shapekey */
+ // FIXME: is owner-id and having no owner/dopesheet really fine?
+ if (key->adt && key->adt->action)
+ items= animdata_filter_action(anim_data, NULL, key->adt->action, filter_mode, NULL, ANIMTYPE_NONE, (ID *)key);
+ }
+
+ /* return the number of items added to the list */
+ return items;
+}
+
#if 0
// FIXME: switch this to use the bDopeSheet...
static int animdata_filter_gpencil (ListBase *anim_data, bScreen *sc, int filter_mode)
@@ -1944,9 +2018,11 @@ int ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_mode
}
break;
- case ANIMCONT_SHAPEKEY:
+ case ANIMCONT_SHAPEKEY: /* 'ShapeKey Editor' */
{
- //items= animdata_filter_shapekey(anim_data, data, filter_mode, NULL, ANIMTYPE_NONE, (ID *)obact);
+ /* the check for the DopeSheet summary is included here since the summary works here too */
+ if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
+ items= animdata_filter_shapekey(anim_data, data, filter_mode);
}
break;
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 271827c2aba..316f1b58d33 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -99,7 +99,7 @@ typedef struct bAnimListElem {
void *data; /* source data this elem represents */
int type; /* one of the ANIMTYPE_* values */
int flag; /* copy of elem's flags for quick access */
- int index; /* copy of adrcode where applicable */
+ int index; /* for un-named data, the index of the data in it's collection */
void *key_data; /* motion data - mostly F-Curves, but can be other types too */
short datatype; /* type of motion data to expect */
@@ -144,7 +144,7 @@ typedef enum eAnim_ChannelType {
ANIMTYPE_DSMBALL,
ANIMTYPE_DSARM,
- ANIMTYPE_SHAPEKEY, // XXX probably can become depreceated???
+ ANIMTYPE_SHAPEKEY,
ANIMTYPE_GPDATABLOCK,
ANIMTYPE_GPLAYER,
@@ -209,7 +209,7 @@ typedef enum eAnimFilter_Flags {
#define FILTER_MAT_OBJC(ob) ((ob->nlaflag & OB_ADS_SHOWMATS))
#define FILTER_PART_OBJC(ob) ((ob->nlaflag & OB_ADS_SHOWPARTS))
/* 'Sub-object' channels (flags stored in Data block) */
-#define FILTER_SKE_OBJD(key) ((key->flag & KEYBLOCK_DS_EXPAND))
+#define FILTER_SKE_OBJD(key) ((key->flag & KEY_DS_EXPAND))
#define FILTER_MAT_OBJD(ma) ((ma->flag & MA_DS_EXPAND))
#define FILTER_LAM_OBJD(la) ((la->flag & LA_DS_EXPAND))
#define FILTER_CAM_OBJD(ca) ((ca->flag & CAM_DS_EXPAND))
@@ -232,6 +232,10 @@ typedef enum eAnimFilter_Flags {
#define EDITABLE_FCU(fcu) ((fcu->flag & FCURVE_PROTECTED)==0)
#define SEL_FCU(fcu) (fcu->flag & (FCURVE_ACTIVE|FCURVE_SELECTED))
+/* ShapeKey mode only */
+#define EDITABLE_SHAPEKEY(kb) ((kb->flag & KEYBLOCK_LOCKED)==0)
+#define SEL_SHAPEKEY(kb) (kb->flag & KEYBLOCK_SEL)
+
/* Grease Pencil only */
/* Grease Pencil datablock settings */
#define EXPANDED_GPD(gpd) (gpd->flag & GP_DATA_EXPAND)
diff --git a/source/blender/makesdna/DNA_key_types.h b/source/blender/makesdna/DNA_key_types.h
index c42e555d562..e86abf12424 100644
--- a/source/blender/makesdna/DNA_key_types.h
+++ b/source/blender/makesdna/DNA_key_types.h
@@ -80,6 +80,7 @@ typedef struct Key {
#define KEY_RELATIVE 1
/* key->flag */
+#define KEY_DS_EXPAND 1
/* keyblock->type */
#define KEY_LINEAR 0
@@ -87,8 +88,9 @@ typedef struct Key {
#define KEY_BSPLINE 2
/* keyblock->flag */
-#define KEYBLOCK_MUTE 1
-#define KEYBLOCK_DS_EXPAND 2
+#define KEYBLOCK_MUTE (1<<0)
+#define KEYBLOCK_SEL (1<<1)
+#define KEYBLOCK_LOCKED (1<<2)
#endif