Keyframe Checking (i.e. does given frame have a keyframe) is now implemented in the keyframing api.
Replaced the method used in to check if there's a keyframe on the current frame, when drawing the active object name / frame number info with this new code. - It should in theory be faster than the previous code, as it doesn't have to build an entire list everytime of all keyframes, and also uses more efficient search method. - Added some settings to control what sources of animation data are used (per 3d-view). Can be found in the View Properties panel. This should be stable... release builders should ignore this commit for now (to avoid having differences between release candidates).
This commit is contained in:
@@ -65,7 +65,7 @@ enum {
|
||||
/* -------- */
|
||||
|
||||
/* Main Keyframing API calls:
|
||||
* Use this to create any necessary animation data,, and then insert a keyframe
|
||||
* Use this to create any necessary animation data, and then insert a keyframe
|
||||
* using the current value being keyframed, in the relevant place. Returns success.
|
||||
*/
|
||||
// TODO: adapt this for new data-api -> this blocktype, etc. stuff is evil!
|
||||
@@ -104,18 +104,28 @@ void common_deletekey(void);
|
||||
|
||||
/* ************ Keyframe Checking ******************** */
|
||||
|
||||
/* Checks whether a keyframe exists for the given ID-block one the given frame */
|
||||
short id_cfra_has_keyframe(struct ID *id, short filter);
|
||||
/* Main Keyframe Checking API call:
|
||||
* Checks whether a keyframe exists for the given ID-block one the given frame.
|
||||
* - It is recommended to call this method over the other keyframe-checkers directly,
|
||||
* in case some detail of the implementation changes...
|
||||
* - frame: the value of this is quite often result of frame_to_float(CFRA)
|
||||
*/
|
||||
short id_frame_has_keyframe(struct ID *id, float frame, short filter);
|
||||
|
||||
/* filter flags fr id_cfra_has_keyframe */
|
||||
/* filter flags for id_cfra_has_keyframe
|
||||
*
|
||||
* WARNING: do not alter order of these, as also stored in files
|
||||
* (for v3d->keyflags)
|
||||
*/
|
||||
enum {
|
||||
/* general */
|
||||
ANIMFILTER_ALL = 0, /* include all available animation data */
|
||||
ANIMFILTER_LOCAL = (1<<0), /* only include locally available anim data */
|
||||
ANIMFILTER_MUTED = (1<<1), /* include muted elements */
|
||||
ANIMFILTER_ACTIVE = (1<<2), /* only include active-subelements */
|
||||
|
||||
/* object specific */
|
||||
ANIMFILTER_MAT = (1<<1), /* include material keyframes too */
|
||||
ANIMFILTER_SKEY = (1<<2), /* shape keys (for geometry) */
|
||||
ANIMFILTER_NOMAT = (1<<9), /* don't include material keyframes */
|
||||
ANIMFILTER_NOSKEY = (1<<10), /* don't include shape keys (for geometry) */
|
||||
} eAnimFilterFlags;
|
||||
|
||||
#endif /* BIF_KEYFRAMING_H */
|
||||
|
||||
@@ -137,7 +137,7 @@ typedef struct View3D {
|
||||
|
||||
short gridsubdiv; /* Number of subdivisions in the grid between each highlighted grid line */
|
||||
|
||||
short pad3;
|
||||
short keyflags; /* flags for display of keyframes */
|
||||
|
||||
char ndofmode; /* mode of transform for 6DOF devices -1 not found, 0 normal, 1 fly, 2 ob transform */
|
||||
char ndoffilter; /*filter for 6DOF devices 0 normal, 1 dominant */
|
||||
|
||||
@@ -437,21 +437,27 @@ static void draw_ob_keys()
|
||||
}
|
||||
|
||||
/* Materials (only relevant for geometry objects) - some filtering might occur */
|
||||
// err... is this ok?
|
||||
filter= (stime->flag & TIME_ONLYACTSEL);
|
||||
for (a=0; a<ob->totcol; a++) {
|
||||
Material *ma= give_current_material(ob, a+1);
|
||||
if (filter) {
|
||||
Material *ma= give_current_material(ob, (ob->actcol + 1));
|
||||
|
||||
/* the only filter we apply right now is only showing the active material */
|
||||
if (filter) {
|
||||
ok= (ob->actcol==a)? 1 : 0;
|
||||
}
|
||||
else ok= 1;
|
||||
|
||||
if (ma && ma->ipo && ok) {
|
||||
/* we only retrieve the active material... */
|
||||
if (ma && ma->ipo) {
|
||||
col[0] = 0xDD; col[1] = 0xA7; col[2] = 0x00;
|
||||
draw_ipo_keys(ma->ipo, col);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (a=0; a<ob->totcol; a++) {
|
||||
Material *ma= give_current_material(ob, a+1);
|
||||
|
||||
if (ma && ma->ipo) {
|
||||
col[0] = 0xDD; col[1] = 0xA7; col[2] = 0x00;
|
||||
draw_ipo_keys(ma->ipo, col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -122,6 +122,7 @@
|
||||
#include "BIF_glutil.h"
|
||||
#include "BIF_interface.h"
|
||||
#include "BIF_interface_icons.h"
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_mywindow.h"
|
||||
#include "BIF_poseobject.h"
|
||||
#include "BIF_previewrender.h"
|
||||
@@ -181,7 +182,7 @@
|
||||
#include "radio.h"
|
||||
|
||||
/* locals */
|
||||
static void drawname(Object *ob);
|
||||
//static void drawname(Object *ob);
|
||||
|
||||
static void star_stuff_init_func(void)
|
||||
{
|
||||
@@ -1199,6 +1200,7 @@ exit:
|
||||
return index;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void drawname(Object *ob)
|
||||
{
|
||||
cpack(0x404040);
|
||||
@@ -1207,6 +1209,7 @@ static void drawname(Object *ob)
|
||||
BMF_DrawString(G.font, " ");
|
||||
BMF_DrawString(G.font, ob->id.name+2);
|
||||
}
|
||||
#endif
|
||||
|
||||
static char *get_cfra_marker_name()
|
||||
{
|
||||
@@ -1217,95 +1220,17 @@ static char *get_cfra_marker_name()
|
||||
for (m1=markers->first, m2=markers->last; m1 && m2; m1=m1->next, m2=m2->prev) {
|
||||
if (m1->frame==CFRA)
|
||||
return m1->name;
|
||||
if (m2->frame==CFRA)
|
||||
return m2->name;
|
||||
|
||||
if (m1 == m2)
|
||||
break;
|
||||
break;
|
||||
|
||||
if (m2->frame==CFRA)
|
||||
return m2->name;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// TODO: move this func into some keyframing API
|
||||
short ob_cfra_has_keyframe (Object *ob)
|
||||
{
|
||||
// fixme... this is slow!
|
||||
if (ob) {
|
||||
ListBase keys = {NULL, NULL};
|
||||
ActKeyColumn *ak, *akn;
|
||||
Key *key= ob_get_key(ob);
|
||||
int cfra, found= 0;
|
||||
|
||||
/* check active action */
|
||||
if (ob->action) {
|
||||
/* get keyframes of action */
|
||||
action_to_keylist(ob->action, &keys, NULL, NULL);
|
||||
|
||||
cfra= frame_to_float(CFRA);
|
||||
cfra= get_action_frame(ob, cfra);
|
||||
|
||||
/* check if a keyframe occurs on current frame */
|
||||
for (ak=keys.first, akn=keys.last; ak && akn; ak=ak->next, akn=akn->prev) {
|
||||
if (cfra == ak->cfra) {
|
||||
found= 1;
|
||||
break;
|
||||
}
|
||||
else if (cfra == akn->cfra) {
|
||||
found= 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ak == akn)
|
||||
break;
|
||||
}
|
||||
|
||||
/* free temp list */
|
||||
BLI_freelistN(&keys);
|
||||
keys.first= keys.last= NULL;
|
||||
|
||||
/* return if found */
|
||||
if (found) return 1;
|
||||
}
|
||||
|
||||
/* accumulate keyframes for available ipo's */
|
||||
if (ob->ipo)
|
||||
ipo_to_keylist(ob->ipo, &keys, NULL, NULL);
|
||||
if (key)
|
||||
ipo_to_keylist(key->ipo, &keys, NULL, NULL);
|
||||
|
||||
if (keys.first) {
|
||||
cfra= frame_to_float(CFRA);
|
||||
found= 0;
|
||||
|
||||
/* check if a keyframe occurs on current frame */
|
||||
for (ak=keys.first, akn=keys.last; ak && akn; ak=ak->next, akn=akn->prev) {
|
||||
if (IS_EQ(cfra, ak->cfra)) {
|
||||
found= 1;
|
||||
break;
|
||||
}
|
||||
else if (IS_EQ(cfra, akn->cfra)) {
|
||||
found= 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ak == akn)
|
||||
break;
|
||||
}
|
||||
|
||||
/* free temp list */
|
||||
BLI_freelistN(&keys);
|
||||
keys.first= keys.last= NULL;
|
||||
|
||||
/* return if found */
|
||||
if (found) return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* couldn't find a keyframe */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* draw info beside axes in bottom left-corner:
|
||||
* framenum, object name, bone name (if available), marker name (if available)
|
||||
*/
|
||||
@@ -1382,7 +1307,7 @@ static void draw_selected_name(Object *ob)
|
||||
}
|
||||
|
||||
/* colour depends on whether there is a keyframe */
|
||||
if (ob_cfra_has_keyframe(ob))
|
||||
if (id_frame_has_keyframe((ID *)ob, frame_to_float(CFRA), G.vd->keyflags))
|
||||
BIF_ThemeColor(TH_VERTEX_SELECT);
|
||||
else
|
||||
BIF_ThemeColor(TH_TEXT_HI);
|
||||
@@ -2609,7 +2534,6 @@ static void view3d_panel_properties(short cntrl) // VIEW3D_HANDLER_SETTINGS
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
uiDefBut(block, LABEL, 1, "Display:", 10, 50, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitS(block, TOG, V3D_SELECT_OUTLINE, REDRAWVIEW3D, "Outline Selected", 10, 30, 140, 19, &vd->flag, 0, 0, 0, 0, "Highlight selected objects with an outline, in Solid, Shaded or Textured viewport shading modes");
|
||||
uiDefButBitS(block, TOG, V3D_DRAW_CENTERS, REDRAWVIEW3D, "All Object Centers", 10, 10, 140, 19, &vd->flag, 0, 0, 0, 0, "Draw the center points on all objects");
|
||||
@@ -2617,11 +2541,21 @@ static void view3d_panel_properties(short cntrl) // VIEW3D_HANDLER_SETTINGS
|
||||
uiDefButBitS(block, TOG, V3D_SOLID_TEX, REDRAWVIEW3D, "Solid Tex", 10, -30, 140, 19, &vd->flag2, 0, 0, 0, 0, "Display textures in Solid draw type (Shift T)");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
uiDefBut(block, LABEL, 1, "View Locking:", 160, 50, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
|
||||
uiDefBut(block, LABEL, 1, "View Locking:", 160, 60, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefIDPoinBut(block, test_obpoin_but, ID_OB, REDRAWVIEW3D, "Object:", 160, 30, 140, 19, &vd->ob_centre, "Lock view to center to this Object");
|
||||
uiDefBut(block, TEX, REDRAWVIEW3D, "Bone:", 160, 10, 140, 19, vd->ob_centre_bone, 1, 31, 0, 0, "If view locked to Object, use this Bone to lock to view to");
|
||||
uiDefIDPoinBut(block, test_obpoin_but, ID_OB, REDRAWVIEW3D, "Object:", 160, 40, 140, 19, &vd->ob_centre, "Lock view to center to this Object");
|
||||
uiDefBut(block, TEX, REDRAWVIEW3D, "Bone:", 160, 20, 140, 19, vd->ob_centre_bone, 1, 31, 0, 0, "If view locked to Object, use this Bone to lock to view to");
|
||||
|
||||
uiDefBut(block, LABEL, 1, "Keyframe Display:", 160, -2, 150, 19, NULL, 0.0, 0.0, 0, 0, "");
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButBitS(block, TOG, ANIMFILTER_ACTIVE, REDRAWVIEW3D, "Active",160, -22, 50, 19, &vd->keyflags, 0, 0, 0, 0, "Show keyframes for active element only (i.e. active bone or active material)");
|
||||
uiDefButBitS(block, TOG, ANIMFILTER_MUTED, REDRAWVIEW3D, "Muted",210, -22, 50, 19, &vd->keyflags, 0, 0, 0, 0, "Show keyframes in muted channels");
|
||||
uiDefButBitS(block, TOG, ANIMFILTER_LOCAL, REDRAWVIEW3D, "Local",260, -22, 50, 19, &vd->keyflags, 0, 0, 0, 0, "Show keyframes directly connected to datablock");
|
||||
if ((vd->keyflags & ANIMFILTER_LOCAL)==0) {
|
||||
uiDefButBitS(block, TOGN, ANIMFILTER_NOMAT, REDRAWVIEW3D, "Material",160, -42, 75, 19, &vd->keyflags, 0, 0, 0, 0, "Show keyframes for any available Materials");
|
||||
uiDefButBitS(block, TOGN, ANIMFILTER_NOSKEY, REDRAWVIEW3D, "ShapeKey",235, -42, 75, 19, &vd->keyflags, 0, 0, 0, 0, "Show keyframes for any available Shape Keys");
|
||||
}
|
||||
uiBlockEndAlign(block);
|
||||
}
|
||||
|
||||
static void view3d_panel_preview(ScrArea *sa, short cntrl) // VIEW3D_HANDLER_PREVIEW
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "DNA_constraint_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_ipo_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_lamp_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
@@ -71,7 +72,9 @@
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_ipo.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_material.h"
|
||||
|
||||
#include "BIF_keyframing.h"
|
||||
#include "BIF_butspace.h"
|
||||
@@ -157,11 +160,10 @@ typedef struct bCommonKeySrc {
|
||||
/* Binary search algorithm for finding where to insert BezTriple. (for use by insert_bezt_icu)
|
||||
* Returns the index to insert at (data already at that index will be offset if replace is 0)
|
||||
*/
|
||||
static int binarysearch_bezt_index (BezTriple array[], BezTriple *item, int arraylen, short *replace)
|
||||
static int binarysearch_bezt_index (BezTriple array[], float frame, int arraylen, short *replace)
|
||||
{
|
||||
int start=0, end=arraylen;
|
||||
int loopbreaker= 0, maxloop= arraylen * 2;
|
||||
const float frame= (item)? item->vec[1][0] : 0.0f;
|
||||
|
||||
/* initialise replace-flag first */
|
||||
*replace= 0;
|
||||
@@ -170,7 +172,7 @@ static int binarysearch_bezt_index (BezTriple array[], BezTriple *item, int arra
|
||||
* - keyframe to be added is to be added out of current bounds
|
||||
* - keyframe to be added would replace one of the existing ones on bounds
|
||||
*/
|
||||
if ((arraylen <= 0) || ELEM(NULL, array, item)) {
|
||||
if ((arraylen <= 0) || (array == NULL)) {
|
||||
printf("Warning: binarysearch_bezt_index encountered invalid array \n");
|
||||
return 0;
|
||||
}
|
||||
@@ -250,7 +252,7 @@ int insert_bezt_icu (IpoCurve *icu, BezTriple *bezt)
|
||||
}
|
||||
else {
|
||||
short replace = -1;
|
||||
i = binarysearch_bezt_index(icu->bezt, bezt, icu->totvert, &replace);
|
||||
i = binarysearch_bezt_index(icu->bezt, bezt->vec[1][0], icu->totvert, &replace);
|
||||
|
||||
if (replace) {
|
||||
/* sanity check: 'i' may in rare cases exceed arraylen */
|
||||
@@ -841,7 +843,6 @@ short deletekey (ID *id, int blocktype, char *actname, char *constname, int adrc
|
||||
|
||||
/* only continue if we have an ipo-curve to remove keyframes from */
|
||||
if (icu) {
|
||||
BezTriple bezt;
|
||||
float cfra = frame_to_float(CFRA);
|
||||
short found = -1;
|
||||
int i;
|
||||
@@ -861,12 +862,8 @@ short deletekey (ID *id, int blocktype, char *actname, char *constname, int adrc
|
||||
}
|
||||
}
|
||||
|
||||
/* only need to set bezt->vec[1][0], as that's all binarysearch uses */
|
||||
memset(&bezt, 0, sizeof(BezTriple));
|
||||
bezt.vec[1][0]= cfra;
|
||||
|
||||
/* try to find index of beztriple to get rid of */
|
||||
i = binarysearch_bezt_index(icu->bezt, &bezt, icu->totvert, &found);
|
||||
i = binarysearch_bezt_index(icu->bezt, cfra, icu->totvert, &found);
|
||||
if (found) {
|
||||
/* delete the key at the index (will sanity check + do recalc afterwards ) */
|
||||
delete_icu_key(icu, i, 1);
|
||||
@@ -1898,3 +1895,198 @@ void common_deletekey (void)
|
||||
}
|
||||
|
||||
/* ************************************************** */
|
||||
/* KEYFRAME DETECTION */
|
||||
|
||||
/* --------------- API/Per-Datablock Handling ------------------- */
|
||||
|
||||
/* Checks whether an IPO-block has a keyframe for a given frame
|
||||
* Since we're only concerned whether a keyframe exists, we can simply loop until a match is found...
|
||||
*/
|
||||
short ipo_frame_has_keyframe (Ipo *ipo, float frame, short filter)
|
||||
{
|
||||
IpoCurve *icu;
|
||||
|
||||
/* can only find if there is data */
|
||||
if (ipo == NULL)
|
||||
return 0;
|
||||
|
||||
/* if only check non-muted, check if muted */
|
||||
if ((filter & ANIMFILTER_MUTED) || (ipo->muteipo))
|
||||
return 0;
|
||||
|
||||
/* loop over IPO-curves, using binary-search to try to find matches
|
||||
* - this assumes that keyframes are only beztriples
|
||||
*/
|
||||
for (icu= ipo->curve.first; icu; icu= icu->next) {
|
||||
/* we either include all regardless of muting, or only non-muted */
|
||||
if ((filter & ANIMFILTER_MUTED) || (icu->flag & IPO_MUTE)==0) {
|
||||
short replace = -1;
|
||||
int i = binarysearch_bezt_index(icu->bezt, frame, icu->totvert, &replace);
|
||||
|
||||
/* binarysearch_bezt_index will set replace to be 0 or 1
|
||||
* - obviously, 1 represents a match
|
||||
*/
|
||||
if (replace) {
|
||||
/* sanity check: 'i' may in rare cases exceed arraylen */
|
||||
if ((i >= 0) && (i < icu->totvert))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* nothing found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Checks whether an action-block has a keyframe for a given frame
|
||||
* Since we're only concerned whether a keyframe exists, we can simply loop until a match is found...
|
||||
*/
|
||||
short action_frame_has_keyframe (bAction *act, float frame, short filter)
|
||||
{
|
||||
bActionChannel *achan;
|
||||
|
||||
/* error checking */
|
||||
if (act == NULL)
|
||||
return 0;
|
||||
|
||||
/* check thorugh action-channels for match */
|
||||
for (achan= act->chanbase.first; achan; achan= achan->next) {
|
||||
/* we either include all regardless of muting, or only non-muted
|
||||
* - here we include 'hidden' channels in the muted definition
|
||||
*/
|
||||
if ((filter & ANIMFILTER_MUTED) || (achan->flag & ACHAN_HIDDEN)==0) {
|
||||
if (ipo_frame_has_keyframe(achan->ipo, frame, filter))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* nothing found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Checks whether an Object has a keyframe for a given frame */
|
||||
short object_frame_has_keyframe (Object *ob, float frame, short filter)
|
||||
{
|
||||
/* error checking */
|
||||
if (ob == NULL)
|
||||
return 0;
|
||||
|
||||
/* check for an action - actions take priority over normal IPO's */
|
||||
if (ob->action) {
|
||||
float aframe;
|
||||
|
||||
/* apply nla-action scaling if needed */
|
||||
if ((ob->nlaflag & OB_NLA_OVERRIDE) && (ob->nlastrips.first))
|
||||
aframe= get_action_frame(ob, frame);
|
||||
else
|
||||
aframe= frame;
|
||||
|
||||
/* priority check here goes to pose-channel checks (for armatures) */
|
||||
if ((ob->pose) && (ob->flag & OB_POSEMODE)) {
|
||||
/* only relevant check here is to only show active... */
|
||||
if (filter & ANIMFILTER_ACTIVE) {
|
||||
bPoseChannel *pchan= get_active_posechannel(ob);
|
||||
bActionChannel *achan= (pchan) ? get_action_channel(ob->action, pchan->name) : NULL;
|
||||
|
||||
/* since we're only interested in whether the selected one has any keyframes... */
|
||||
return (achan && ipo_frame_has_keyframe(achan->ipo, aframe, filter));
|
||||
}
|
||||
}
|
||||
|
||||
/* for everything else, just use the standard test (only return if success) */
|
||||
if (action_frame_has_keyframe(ob->action, aframe, filter))
|
||||
return 1;
|
||||
}
|
||||
else if (ob->ipo) {
|
||||
/* only return if success */
|
||||
if (ipo_frame_has_keyframe(ob->ipo, frame, filter))
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* try shapekey keyframes (if available, and allowed by filter) */
|
||||
if ( !(filter & ANIMFILTER_LOCAL) && !(filter & ANIMFILTER_NOSKEY) ) {
|
||||
Key *key= ob_get_key(ob);
|
||||
|
||||
/* shapekeys can have keyframes ('Relative Shape Keys')
|
||||
* or depend on time (old 'Absolute Shape Keys')
|
||||
*/
|
||||
|
||||
/* 1. test for relative (with keyframes) */
|
||||
if (id_frame_has_keyframe((ID *)key, frame, filter))
|
||||
return 1;
|
||||
|
||||
/* 2. test for time */
|
||||
// TODO... yet to be implemented (this feature may evolve before then anyway)
|
||||
}
|
||||
|
||||
/* try materials */
|
||||
if ( !(filter & ANIMFILTER_LOCAL) && !(filter & ANIMFILTER_NOMAT) ) {
|
||||
/* if only active, then we can skip a lot of looping */
|
||||
if (filter & ANIMFILTER_ACTIVE) {
|
||||
Material *ma= give_current_material(ob, (ob->actcol + 1));
|
||||
|
||||
/* we only retrieve the active material... */
|
||||
if (id_frame_has_keyframe((ID *)ma, frame, filter))
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
int a;
|
||||
|
||||
/* loop over materials */
|
||||
for (a=0; a<ob->totcol; a++) {
|
||||
Material *ma= give_current_material(ob, a+1);
|
||||
|
||||
if (id_frame_has_keyframe((ID *)ma, frame, filter))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* nothing found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------- API ------------------- */
|
||||
|
||||
/* Checks whether a keyframe exists for the given ID-block one the given frame */
|
||||
short id_frame_has_keyframe (ID *id, float frame, short filter)
|
||||
{
|
||||
/* error checking */
|
||||
if (id == NULL)
|
||||
return 0;
|
||||
|
||||
/* check for a valid id-type */
|
||||
switch (GS(id->name)) {
|
||||
/* animation data-types */
|
||||
case ID_IP: /* ipo */
|
||||
return ipo_frame_has_keyframe((Ipo *)id, frame, filter);
|
||||
case ID_AC: /* action */
|
||||
return action_frame_has_keyframe((bAction *)id, frame, filter);
|
||||
|
||||
case ID_OB: /* object */
|
||||
return object_frame_has_keyframe((Object *)id, frame, filter);
|
||||
|
||||
case ID_MA: /* material */
|
||||
{
|
||||
Material *ma= (Material *)id;
|
||||
|
||||
/* currently, material's only have an ipo-block */
|
||||
return ipo_frame_has_keyframe(ma->ipo, frame, filter);
|
||||
}
|
||||
break;
|
||||
|
||||
case ID_KE: /* shapekey */
|
||||
{
|
||||
Key *key= (Key *)id;
|
||||
|
||||
/* currently, shapekey's only have an ipo-block */
|
||||
return ipo_frame_has_keyframe(key->ipo, frame, filter);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* no keyframe found */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ************************************************** */
|
||||
|
||||
Reference in New Issue
Block a user