diff options
Diffstat (limited to 'source/blender/makesrna/intern/rna_nla.c')
-rw-r--r-- | source/blender/makesrna/intern/rna_nla.c | 1368 |
1 files changed, 725 insertions, 643 deletions
diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index 5ec46c43734..7573d2cdc05 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -39,405 +39,421 @@ #ifdef RNA_RUNTIME -#include <stdio.h> -#include <math.h> +# include <stdio.h> +# include <math.h> /* needed for some of the validation stuff... */ -#include "BKE_animsys.h" -#include "BKE_fcurve.h" -#include "BKE_nla.h" +# include "BKE_animsys.h" +# include "BKE_fcurve.h" +# include "BKE_nla.h" -#include "DNA_object_types.h" +# include "DNA_object_types.h" -#include "ED_anim_api.h" +# include "ED_anim_api.h" -#include "DEG_depsgraph_build.h" -#include "DEG_depsgraph.h" +# include "DEG_depsgraph_build.h" +# include "DEG_depsgraph.h" /* temp constant defined for these funcs only... */ -#define NLASTRIP_MIN_LEN_THRESH 0.1f +# define NLASTRIP_MIN_LEN_THRESH 0.1f static void rna_NlaStrip_name_set(PointerRNA *ptr, const char *value) { - NlaStrip *data = (NlaStrip *)ptr->data; + NlaStrip *data = (NlaStrip *)ptr->data; - /* copy the name first */ - BLI_strncpy_utf8(data->name, value, sizeof(data->name)); + /* copy the name first */ + BLI_strncpy_utf8(data->name, value, sizeof(data->name)); - /* validate if there's enough info to do so */ - if (ptr->id.data) { - AnimData *adt = BKE_animdata_from_id(ptr->id.data); - BKE_nlastrip_validate_name(adt, data); - } + /* validate if there's enough info to do so */ + if (ptr->id.data) { + AnimData *adt = BKE_animdata_from_id(ptr->id.data); + BKE_nlastrip_validate_name(adt, data); + } } static char *rna_NlaStrip_path(PointerRNA *ptr) { - NlaStrip *strip = (NlaStrip *)ptr->data; - AnimData *adt = BKE_animdata_from_id(ptr->id.data); - - /* if we're attached to AnimData, try to resolve path back to AnimData */ - if (adt) { - NlaTrack *nlt; - NlaStrip *nls; - - for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) { - for (nls = nlt->strips.first; nls; nls = nls->next) { - if (nls == strip) { - /* XXX but if we animate like this, the control will never work... */ - char name_esc_nlt[sizeof(nlt->name) * 2]; - char name_esc_strip[sizeof(strip->name) * 2]; - - BLI_strescape(name_esc_nlt, nlt->name, sizeof(name_esc_nlt)); - BLI_strescape(name_esc_strip, strip->name, sizeof(name_esc_strip)); - return BLI_sprintfN("animation_data.nla_tracks[\"%s\"].strips[\"%s\"]", - name_esc_nlt, name_esc_strip); - } - } - } - } - - /* no path */ - return BLI_strdup(""); + NlaStrip *strip = (NlaStrip *)ptr->data; + AnimData *adt = BKE_animdata_from_id(ptr->id.data); + + /* if we're attached to AnimData, try to resolve path back to AnimData */ + if (adt) { + NlaTrack *nlt; + NlaStrip *nls; + + for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) { + for (nls = nlt->strips.first; nls; nls = nls->next) { + if (nls == strip) { + /* XXX but if we animate like this, the control will never work... */ + char name_esc_nlt[sizeof(nlt->name) * 2]; + char name_esc_strip[sizeof(strip->name) * 2]; + + BLI_strescape(name_esc_nlt, nlt->name, sizeof(name_esc_nlt)); + BLI_strescape(name_esc_strip, strip->name, sizeof(name_esc_strip)); + return BLI_sprintfN( + "animation_data.nla_tracks[\"%s\"].strips[\"%s\"]", name_esc_nlt, name_esc_strip); + } + } + } + } + + /* no path */ + return BLI_strdup(""); } static void rna_NlaStrip_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { - ID *id = ptr->id.data; + ID *id = ptr->id.data; - ANIM_id_update(bmain, id); + ANIM_id_update(bmain, id); } static void rna_NlaStrip_dependency_update(Main *bmain, Scene *scene, PointerRNA *ptr) { - DEG_relations_tag_update(bmain); + DEG_relations_tag_update(bmain); - rna_NlaStrip_update(bmain, scene, ptr); + rna_NlaStrip_update(bmain, scene, ptr); } static void rna_NlaStrip_transform_update(Main *bmain, Scene *scene, PointerRNA *ptr) { - NlaStrip *strip = (NlaStrip *)ptr->data; + NlaStrip *strip = (NlaStrip *)ptr->data; - BKE_nlameta_flush_transforms(strip); + BKE_nlameta_flush_transforms(strip); - /* set the flag */ - if ((strip->flag & NLASTRIP_FLAG_AUTO_BLENDS) && ptr->id.data) { - /* validate state to ensure that auto-blend gets applied immediately */ - IdAdtTemplate *iat = (IdAdtTemplate *)ptr->id.data; + /* set the flag */ + if ((strip->flag & NLASTRIP_FLAG_AUTO_BLENDS) && ptr->id.data) { + /* validate state to ensure that auto-blend gets applied immediately */ + IdAdtTemplate *iat = (IdAdtTemplate *)ptr->id.data; - if (iat->adt) { - BKE_nla_validate_state(iat->adt); - } - } + if (iat->adt) { + BKE_nla_validate_state(iat->adt); + } + } - rna_NlaStrip_update(bmain, scene, ptr); + rna_NlaStrip_update(bmain, scene, ptr); } static void rna_NlaStrip_start_frame_set(PointerRNA *ptr, float value) { - NlaStrip *data = (NlaStrip *)ptr->data; - - /* clamp value to lie within valid limits - * - cannot start past the end of the strip + some flexibility threshold - * - cannot start before the previous strip (if present) ends - * -> but if it was a transition, we could go up to the start of the strip + some flexibility threshold - * as long as we re-adjust the transition afterwards - * - minimum frame is -MAXFRAME so that we don't get clipping on frame 0 - */ - if (data->prev) { - if (data->prev->type == NLASTRIP_TYPE_TRANSITION) { - CLAMP(value, data->prev->start + NLASTRIP_MIN_LEN_THRESH, data->end - NLASTRIP_MIN_LEN_THRESH); - - /* re-adjust the transition to stick to the endpoints of the action-clips */ - data->prev->end = value; - } - else { - CLAMP(value, data->prev->end, data->end - NLASTRIP_MIN_LEN_THRESH); - } - } - else { - CLAMP(value, MINAFRAME, data->end); - } - data->start = value; + NlaStrip *data = (NlaStrip *)ptr->data; + + /* clamp value to lie within valid limits + * - cannot start past the end of the strip + some flexibility threshold + * - cannot start before the previous strip (if present) ends + * -> but if it was a transition, we could go up to the start of the strip + some flexibility threshold + * as long as we re-adjust the transition afterwards + * - minimum frame is -MAXFRAME so that we don't get clipping on frame 0 + */ + if (data->prev) { + if (data->prev->type == NLASTRIP_TYPE_TRANSITION) { + CLAMP( + value, data->prev->start + NLASTRIP_MIN_LEN_THRESH, data->end - NLASTRIP_MIN_LEN_THRESH); + + /* re-adjust the transition to stick to the endpoints of the action-clips */ + data->prev->end = value; + } + else { + CLAMP(value, data->prev->end, data->end - NLASTRIP_MIN_LEN_THRESH); + } + } + else { + CLAMP(value, MINAFRAME, data->end); + } + data->start = value; } static void rna_NlaStrip_end_frame_set(PointerRNA *ptr, float value) { - NlaStrip *data = (NlaStrip *)ptr->data; - - /* clamp value to lie within valid limits - * - must not have zero or negative length strip, so cannot start before the first frame - * + some minimum-strip-length threshold - * - cannot end later than the start of the next strip (if present) - * -> but if it was a transition, we could go up to the start of the end - some flexibility threshold - * as long as we re-adjust the transition afterwards - */ - if (data->next) { - if (data->next->type == NLASTRIP_TYPE_TRANSITION) { - CLAMP(value, data->start + NLASTRIP_MIN_LEN_THRESH, data->next->end - NLASTRIP_MIN_LEN_THRESH); - - /* readjust the transition to stick to the endpoints of the action-clips */ - data->next->start = value; - } - else { - CLAMP(value, data->start + NLASTRIP_MIN_LEN_THRESH, data->next->start); - } - } - else { - CLAMP(value, data->start + NLASTRIP_MIN_LEN_THRESH, MAXFRAME); - } - data->end = value; - - - /* calculate the lengths the strip and its action (if applicable) */ - if (data->type == NLASTRIP_TYPE_CLIP) { - float len, actlen; - - len = data->end - data->start; - actlen = data->actend - data->actstart; - if (IS_EQF(actlen, 0.0f)) actlen = 1.0f; - - /* now, adjust the 'scale' setting to reflect this (so that this change can be valid) */ - data->scale = len / ((actlen) * data->repeat); - } + NlaStrip *data = (NlaStrip *)ptr->data; + + /* clamp value to lie within valid limits + * - must not have zero or negative length strip, so cannot start before the first frame + * + some minimum-strip-length threshold + * - cannot end later than the start of the next strip (if present) + * -> but if it was a transition, we could go up to the start of the end - some flexibility threshold + * as long as we re-adjust the transition afterwards + */ + if (data->next) { + if (data->next->type == NLASTRIP_TYPE_TRANSITION) { + CLAMP( + value, data->start + NLASTRIP_MIN_LEN_THRESH, data->next->end - NLASTRIP_MIN_LEN_THRESH); + + /* readjust the transition to stick to the endpoints of the action-clips */ + data->next->start = value; + } + else { + CLAMP(value, data->start + NLASTRIP_MIN_LEN_THRESH, data->next->start); + } + } + else { + CLAMP(value, data->start + NLASTRIP_MIN_LEN_THRESH, MAXFRAME); + } + data->end = value; + + /* calculate the lengths the strip and its action (if applicable) */ + if (data->type == NLASTRIP_TYPE_CLIP) { + float len, actlen; + + len = data->end - data->start; + actlen = data->actend - data->actstart; + if (IS_EQF(actlen, 0.0f)) + actlen = 1.0f; + + /* now, adjust the 'scale' setting to reflect this (so that this change can be valid) */ + data->scale = len / ((actlen)*data->repeat); + } } static void rna_NlaStrip_scale_set(PointerRNA *ptr, float value) { - NlaStrip *data = (NlaStrip *)ptr->data; + NlaStrip *data = (NlaStrip *)ptr->data; - /* set scale value */ - /* NOTE: these need to be synced with the values in the property definition in rna_def_nlastrip() */ - CLAMP(value, 0.0001f, 1000.0f); - data->scale = value; + /* set scale value */ + /* NOTE: these need to be synced with the values in the property definition in rna_def_nlastrip() */ + CLAMP(value, 0.0001f, 1000.0f); + data->scale = value; - /* adjust the strip extents in response to this */ - BKE_nlastrip_recalculate_bounds(data); + /* adjust the strip extents in response to this */ + BKE_nlastrip_recalculate_bounds(data); } static void rna_NlaStrip_repeat_set(PointerRNA *ptr, float value) { - NlaStrip *data = (NlaStrip *)ptr->data; + NlaStrip *data = (NlaStrip *)ptr->data; - /* set repeat value */ - /* NOTE: these need to be synced with the values in the property definition in rna_def_nlastrip() */ - CLAMP(value, 0.01f, 1000.0f); - data->repeat = value; + /* set repeat value */ + /* NOTE: these need to be synced with the values in the property definition in rna_def_nlastrip() */ + CLAMP(value, 0.01f, 1000.0f); + data->repeat = value; - /* adjust the strip extents in response to this */ - BKE_nlastrip_recalculate_bounds(data); + /* adjust the strip extents in response to this */ + BKE_nlastrip_recalculate_bounds(data); } static void rna_NlaStrip_blend_in_set(PointerRNA *ptr, float value) { - NlaStrip *data = (NlaStrip *)ptr->data; - float len; + NlaStrip *data = (NlaStrip *)ptr->data; + float len; - /* blend-in is limited to the length of the strip, and also cannot overlap with blendout */ - len = (data->end - data->start) - data->blendout; - CLAMP(value, 0, len); + /* blend-in is limited to the length of the strip, and also cannot overlap with blendout */ + len = (data->end - data->start) - data->blendout; + CLAMP(value, 0, len); - data->blendin = value; + data->blendin = value; } static void rna_NlaStrip_blend_out_set(PointerRNA *ptr, float value) { - NlaStrip *data = (NlaStrip *)ptr->data; - float len; + NlaStrip *data = (NlaStrip *)ptr->data; + float len; - /* blend-out is limited to the length of the strip */ - len = (data->end - data->start); - CLAMP(value, 0, len); + /* blend-out is limited to the length of the strip */ + len = (data->end - data->start); + CLAMP(value, 0, len); - /* it also cannot overlap with blendin */ - if ((len - value) < data->blendin) - value = len - data->blendin; + /* it also cannot overlap with blendin */ + if ((len - value) < data->blendin) + value = len - data->blendin; - data->blendout = value; + data->blendout = value; } static void rna_NlaStrip_use_auto_blend_set(PointerRNA *ptr, bool value) { - NlaStrip *data = (NlaStrip *)ptr->data; - - if (value) { - /* set the flag */ - data->flag |= NLASTRIP_FLAG_AUTO_BLENDS; - - /* validate state to ensure that auto-blend gets applied immediately */ - if (ptr->id.data) { - IdAdtTemplate *iat = (IdAdtTemplate *)ptr->id.data; - - if (iat->adt) { - BKE_nla_validate_state(iat->adt); - } - } - } - else { - /* clear the flag */ - data->flag &= ~NLASTRIP_FLAG_AUTO_BLENDS; - - /* clear the values too, so that it's clear that there has been an effect */ - /* TODO: it's somewhat debatable whether it's better to leave these in instead... */ - data->blendin = 0.0f; - data->blendout = 0.0f; - } + NlaStrip *data = (NlaStrip *)ptr->data; + + if (value) { + /* set the flag */ + data->flag |= NLASTRIP_FLAG_AUTO_BLENDS; + + /* validate state to ensure that auto-blend gets applied immediately */ + if (ptr->id.data) { + IdAdtTemplate *iat = (IdAdtTemplate *)ptr->id.data; + + if (iat->adt) { + BKE_nla_validate_state(iat->adt); + } + } + } + else { + /* clear the flag */ + data->flag &= ~NLASTRIP_FLAG_AUTO_BLENDS; + + /* clear the values too, so that it's clear that there has been an effect */ + /* TODO: it's somewhat debatable whether it's better to leave these in instead... */ + data->blendin = 0.0f; + data->blendout = 0.0f; + } } static int rna_NlaStrip_action_editable(PointerRNA *ptr, const char **UNUSED(r_info)) { - NlaStrip *strip = (NlaStrip *)ptr->data; + NlaStrip *strip = (NlaStrip *)ptr->data; - /* strip actions shouldn't be editable if NLA tweakmode is on */ - if (ptr->id.data) { - AnimData *adt = BKE_animdata_from_id(ptr->id.data); + /* strip actions shouldn't be editable if NLA tweakmode is on */ + if (ptr->id.data) { + AnimData *adt = BKE_animdata_from_id(ptr->id.data); - if (adt) { - /* active action is only editable when it is not a tweaking strip */ - if ((adt->flag & ADT_NLA_EDIT_ON) || (adt->actstrip) || (adt->tmpact)) - return 0; - } - } + if (adt) { + /* active action is only editable when it is not a tweaking strip */ + if ((adt->flag & ADT_NLA_EDIT_ON) || (adt->actstrip) || (adt->tmpact)) + return 0; + } + } - /* check for clues that strip probably shouldn't be used... */ - if (strip->flag & NLASTRIP_FLAG_TWEAKUSER) - return 0; + /* check for clues that strip probably shouldn't be used... */ + if (strip->flag & NLASTRIP_FLAG_TWEAKUSER) + return 0; - /* should be ok, though we may still miss some cases */ - return PROP_EDITABLE; + /* should be ok, though we may still miss some cases */ + return PROP_EDITABLE; } static void rna_NlaStrip_action_start_frame_set(PointerRNA *ptr, float value) { - NlaStrip *data = (NlaStrip *)ptr->data; + NlaStrip *data = (NlaStrip *)ptr->data; - /* prevent start frame from occurring after end of action */ - CLAMP(value, MINAFRAME, data->actend); - data->actstart = value; + /* prevent start frame from occurring after end of action */ + CLAMP(value, MINAFRAME, data->actend); + data->actstart = value; - /* adjust the strip extents in response to this */ - /* TODO: should the strip be moved backwards instead as a special case? */ - BKE_nlastrip_recalculate_bounds(data); + /* adjust the strip extents in response to this */ + /* TODO: should the strip be moved backwards instead as a special case? */ + BKE_nlastrip_recalculate_bounds(data); } static void rna_NlaStrip_action_end_frame_set(PointerRNA *ptr, float value) { - NlaStrip *data = (NlaStrip *)ptr->data; + NlaStrip *data = (NlaStrip *)ptr->data; - /* prevent end frame from starting before start of action */ - CLAMP(value, data->actstart, MAXFRAME); - data->actend = value; + /* prevent end frame from starting before start of action */ + CLAMP(value, data->actstart, MAXFRAME); + data->actend = value; - /* adjust the strip extents in response to this */ - BKE_nlastrip_recalculate_bounds(data); + /* adjust the strip extents in response to this */ + BKE_nlastrip_recalculate_bounds(data); } static void rna_NlaStrip_animated_influence_set(PointerRNA *ptr, bool value) { - NlaStrip *data = (NlaStrip *)ptr->data; - - if (value) { - /* set the flag, then make sure a curve for this exists */ - data->flag |= NLASTRIP_FLAG_USR_INFLUENCE; - BKE_nlastrip_validate_fcurves(data); - } - else - data->flag &= ~NLASTRIP_FLAG_USR_INFLUENCE; + NlaStrip *data = (NlaStrip *)ptr->data; + + if (value) { + /* set the flag, then make sure a curve for this exists */ + data->flag |= NLASTRIP_FLAG_USR_INFLUENCE; + BKE_nlastrip_validate_fcurves(data); + } + else + data->flag &= ~NLASTRIP_FLAG_USR_INFLUENCE; } static void rna_NlaStrip_animated_time_set(PointerRNA *ptr, bool value) { - NlaStrip *data = (NlaStrip *)ptr->data; - - if (value) { - /* set the flag, then make sure a curve for this exists */ - data->flag |= NLASTRIP_FLAG_USR_TIME; - BKE_nlastrip_validate_fcurves(data); - } - else - data->flag &= ~NLASTRIP_FLAG_USR_TIME; + NlaStrip *data = (NlaStrip *)ptr->data; + + if (value) { + /* set the flag, then make sure a curve for this exists */ + data->flag |= NLASTRIP_FLAG_USR_TIME; + BKE_nlastrip_validate_fcurves(data); + } + else + data->flag &= ~NLASTRIP_FLAG_USR_TIME; } -static FCurve *rna_NlaStrip_fcurve_find(NlaStrip *strip, ReportList *reports, const char *data_path, int index) +static FCurve *rna_NlaStrip_fcurve_find(NlaStrip *strip, + ReportList *reports, + const char *data_path, + int index) { - if (data_path[0] == '\0') { - BKE_report(reports, RPT_ERROR, "F-Curve data path empty, invalid argument"); - return NULL; - } + if (data_path[0] == '\0') { + BKE_report(reports, RPT_ERROR, "F-Curve data path empty, invalid argument"); + return NULL; + } - /* Returns NULL if not found. */ - return list_find_fcurve(&strip->fcurves, data_path, index); + /* Returns NULL if not found. */ + return list_find_fcurve(&strip->fcurves, data_path, index); } - -static NlaStrip *rna_NlaStrip_new(ID *id, NlaTrack *track, Main *bmain, bContext *C, ReportList *reports, const char *UNUSED(name), - int start, bAction *action) +static NlaStrip *rna_NlaStrip_new(ID *id, + NlaTrack *track, + Main *bmain, + bContext *C, + ReportList *reports, + const char *UNUSED(name), + int start, + bAction *action) { - NlaStrip *strip = BKE_nlastrip_new(action); - - if (strip == NULL) { - BKE_report(reports, RPT_ERROR, "Unable to create new strip"); - return NULL; - } - - strip->end += (start - strip->start); - strip->start = start; - - if (BKE_nlastrips_add_strip(&track->strips, strip) == 0) { - BKE_report(reports, RPT_ERROR, - "Unable to add strip (the track does not have any space to accommodate this new strip)"); - BKE_nlastrip_free(NULL, strip, true); - return NULL; - } - - /* create dummy AnimData block so that BKE_nlastrip_validate_name() - * can be used to ensure a valid name, as we don't have one here... - * - only the nla_tracks list is needed there, which we aim to reverse engineer here... - */ - { - AnimData adt = {NULL}; - NlaTrack *nlt, *nlt_p; - - /* 'first' NLA track is found by going back up chain of given track's parents until we fall off */ - nlt_p = track; nlt = track; - while ((nlt = nlt->prev) != NULL) - nlt_p = nlt; - adt.nla_tracks.first = nlt_p; - - /* do the same thing to find the last track */ - nlt_p = track; nlt = track; - while ((nlt = nlt->next) != NULL) - nlt_p = nlt; - adt.nla_tracks.last = nlt_p; - - /* now we can just auto-name as usual */ - BKE_nlastrip_validate_name(&adt, strip); - } - - WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, NULL); - - DEG_relations_tag_update(bmain); - DEG_id_tag_update_ex(bmain, id, ID_RECALC_ANIMATION | ID_RECALC_COPY_ON_WRITE); - - return strip; + NlaStrip *strip = BKE_nlastrip_new(action); + + if (strip == NULL) { + BKE_report(reports, RPT_ERROR, "Unable to create new strip"); + return NULL; + } + + strip->end += (start - strip->start); + strip->start = start; + + if (BKE_nlastrips_add_strip(&track->strips, strip) == 0) { + BKE_report( + reports, + RPT_ERROR, + "Unable to add strip (the track does not have any space to accommodate this new strip)"); + BKE_nlastrip_free(NULL, strip, true); + return NULL; + } + + /* create dummy AnimData block so that BKE_nlastrip_validate_name() + * can be used to ensure a valid name, as we don't have one here... + * - only the nla_tracks list is needed there, which we aim to reverse engineer here... + */ + { + AnimData adt = {NULL}; + NlaTrack *nlt, *nlt_p; + + /* 'first' NLA track is found by going back up chain of given track's parents until we fall off */ + nlt_p = track; + nlt = track; + while ((nlt = nlt->prev) != NULL) + nlt_p = nlt; + adt.nla_tracks.first = nlt_p; + + /* do the same thing to find the last track */ + nlt_p = track; + nlt = track; + while ((nlt = nlt->next) != NULL) + nlt_p = nlt; + adt.nla_tracks.last = nlt_p; + + /* now we can just auto-name as usual */ + BKE_nlastrip_validate_name(&adt, strip); + } + + WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_ADDED, NULL); + + DEG_relations_tag_update(bmain); + DEG_id_tag_update_ex(bmain, id, ID_RECALC_ANIMATION | ID_RECALC_COPY_ON_WRITE); + + return strip; } -static void rna_NlaStrip_remove(ID *id, NlaTrack *track, Main *bmain, bContext *C, ReportList *reports, PointerRNA *strip_ptr) +static void rna_NlaStrip_remove( + ID *id, NlaTrack *track, Main *bmain, bContext *C, ReportList *reports, PointerRNA *strip_ptr) { - NlaStrip *strip = strip_ptr->data; - if (BLI_findindex(&track->strips, strip) == -1) { - BKE_reportf(reports, RPT_ERROR, "NLA strip '%s' not found in track '%s'", strip->name, track->name); - return; - } + NlaStrip *strip = strip_ptr->data; + if (BLI_findindex(&track->strips, strip) == -1) { + BKE_reportf( + reports, RPT_ERROR, "NLA strip '%s' not found in track '%s'", strip->name, track->name); + return; + } - BKE_nlastrip_free(&track->strips, strip, true); - RNA_POINTER_INVALIDATE(strip_ptr); + BKE_nlastrip_free(&track->strips, strip, true); + RNA_POINTER_INVALIDATE(strip_ptr); - WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_REMOVED, NULL); + WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_REMOVED, NULL); - DEG_relations_tag_update(bmain); - DEG_id_tag_update_ex(bmain, id, ID_RECALC_ANIMATION | ID_RECALC_COPY_ON_WRITE); + DEG_relations_tag_update(bmain); + DEG_id_tag_update_ex(bmain, id, ID_RECALC_ANIMATION | ID_RECALC_COPY_ON_WRITE); } /* Set the 'solo' setting for the given NLA-track, making sure that it is the only one @@ -445,393 +461,459 @@ static void rna_NlaStrip_remove(ID *id, NlaTrack *track, Main *bmain, bContext * */ static void rna_NlaTrack_solo_set(PointerRNA *ptr, bool value) { - NlaTrack *data = (NlaTrack *)ptr->data; - AnimData *adt = BKE_animdata_from_id(ptr->id.data); - NlaTrack *nt; - - if (data == NULL) { - return; - } - - /* firstly, make sure 'solo' flag for all tracks is disabled */ - for (nt = data; nt; nt = nt->next) { - nt->flag &= ~NLATRACK_SOLO; - } - for (nt = data; nt; nt = nt->prev) { - nt->flag &= ~NLATRACK_SOLO; - } - - /* now, enable 'solo' for the given track if appropriate */ - if (value) { - /* set solo status */ - data->flag |= NLATRACK_SOLO; - - /* set solo-status on AnimData */ - adt->flag |= ADT_NLA_SOLO_TRACK; - } - else { - /* solo status was already cleared on track */ - - /* clear solo-status on AnimData */ - adt->flag &= ~ADT_NLA_SOLO_TRACK; - } + NlaTrack *data = (NlaTrack *)ptr->data; + AnimData *adt = BKE_animdata_from_id(ptr->id.data); + NlaTrack *nt; + + if (data == NULL) { + return; + } + + /* firstly, make sure 'solo' flag for all tracks is disabled */ + for (nt = data; nt; nt = nt->next) { + nt->flag &= ~NLATRACK_SOLO; + } + for (nt = data; nt; nt = nt->prev) { + nt->flag &= ~NLATRACK_SOLO; + } + + /* now, enable 'solo' for the given track if appropriate */ + if (value) { + /* set solo status */ + data->flag |= NLATRACK_SOLO; + + /* set solo-status on AnimData */ + adt->flag |= ADT_NLA_SOLO_TRACK; + } + else { + /* solo status was already cleared on track */ + + /* clear solo-status on AnimData */ + adt->flag &= ~ADT_NLA_SOLO_TRACK; + } } #else /* enum defines exported for rna_animation.c */ const EnumPropertyItem rna_enum_nla_mode_blend_items[] = { - {NLASTRIP_MODE_REPLACE, "REPLACE", 0, "Replace", - "The strip values replace the accumulated results by amount specified by influence"}, - {NLASTRIP_MODE_COMBINE, "COMBINE", 0, "Combine", - "The strip values are combined with accumulated results by appropriately using addition, " - "multiplication, or quaternion math, based on channel type"}, - {0, "", 0, NULL, NULL}, - {NLASTRIP_MODE_ADD, "ADD", 0, "Add", "Weighted result of strip is added to the accumulated results"}, - {NLASTRIP_MODE_SUBTRACT, "SUBTRACT", 0, "Subtract", - "Weighted result of strip is removed from the accumulated results"}, - {NLASTRIP_MODE_MULTIPLY, "MULTIPLY", 0, "Multiply", - "Weighted result of strip is multiplied with the accumulated results"}, - {0, NULL, 0, NULL, NULL}, + {NLASTRIP_MODE_REPLACE, + "REPLACE", + 0, + "Replace", + "The strip values replace the accumulated results by amount specified by influence"}, + {NLASTRIP_MODE_COMBINE, + "COMBINE", + 0, + "Combine", + "The strip values are combined with accumulated results by appropriately using addition, " + "multiplication, or quaternion math, based on channel type"}, + {0, "", 0, NULL, NULL}, + {NLASTRIP_MODE_ADD, + "ADD", + 0, + "Add", + "Weighted result of strip is added to the accumulated results"}, + {NLASTRIP_MODE_SUBTRACT, + "SUBTRACT", + 0, + "Subtract", + "Weighted result of strip is removed from the accumulated results"}, + {NLASTRIP_MODE_MULTIPLY, + "MULTIPLY", + 0, + "Multiply", + "Weighted result of strip is multiplied with the accumulated results"}, + {0, NULL, 0, NULL, NULL}, }; const EnumPropertyItem rna_enum_nla_mode_extend_items[] = { - {NLASTRIP_EXTEND_NOTHING, "NOTHING", 0, "Nothing", "Strip has no influence past its extents"}, - {NLASTRIP_EXTEND_HOLD, "HOLD", 0, "Hold", - "Hold the first frame if no previous strips in track, and always hold last frame"}, - {NLASTRIP_EXTEND_HOLD_FORWARD, "HOLD_FORWARD", 0, "Hold Forward", "Only hold last frame"}, - {0, NULL, 0, NULL, NULL}, + {NLASTRIP_EXTEND_NOTHING, "NOTHING", 0, "Nothing", "Strip has no influence past its extents"}, + {NLASTRIP_EXTEND_HOLD, + "HOLD", + 0, + "Hold", + "Hold the first frame if no previous strips in track, and always hold last frame"}, + {NLASTRIP_EXTEND_HOLD_FORWARD, "HOLD_FORWARD", 0, "Hold Forward", "Only hold last frame"}, + {0, NULL, 0, NULL, NULL}, }; static void rna_def_strip_fcurves(BlenderRNA *brna, PropertyRNA *cprop) { - StructRNA *srna; - - FunctionRNA *func; - PropertyRNA *parm; - - RNA_def_property_srna(cprop, "NlaStripFCurves"); - srna = RNA_def_struct(brna, "NlaStripFCurves", NULL); - RNA_def_struct_sdna(srna, "NlaStrip"); - RNA_def_struct_ui_text(srna, "NLA-Strip F-Curves", "Collection of NLA strip F-Curves"); - - /* Strip.fcurves.find(...) */ - func = RNA_def_function(srna, "find", "rna_NlaStrip_fcurve_find"); - RNA_def_function_ui_description(func, "Find an F-Curve. Note that this function performs a linear scan " - "of all F-Curves in the NLA strip."); - RNA_def_function_flag(func, FUNC_USE_REPORTS); - parm = RNA_def_string(func, "data_path", NULL, 0, "Data Path", "F-Curve data path"); - RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); - RNA_def_int(func, "index", 0, 0, INT_MAX, "Index", "Array index", 0, INT_MAX); - - parm = RNA_def_pointer(func, "fcurve", "FCurve", "", "The found F-Curve, or None if it doesn't exist"); - RNA_def_function_return(func, parm); + StructRNA *srna; + + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "NlaStripFCurves"); + srna = RNA_def_struct(brna, "NlaStripFCurves", NULL); + RNA_def_struct_sdna(srna, "NlaStrip"); + RNA_def_struct_ui_text(srna, "NLA-Strip F-Curves", "Collection of NLA strip F-Curves"); + + /* Strip.fcurves.find(...) */ + func = RNA_def_function(srna, "find", "rna_NlaStrip_fcurve_find"); + RNA_def_function_ui_description( + func, + "Find an F-Curve. Note that this function performs a linear scan " + "of all F-Curves in the NLA strip."); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_string(func, "data_path", NULL, 0, "Data Path", "F-Curve data path"); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + RNA_def_int(func, "index", 0, 0, INT_MAX, "Index", "Array index", 0, INT_MAX); + + parm = RNA_def_pointer( + func, "fcurve", "FCurve", "", "The found F-Curve, or None if it doesn't exist"); + RNA_def_function_return(func, parm); } static void rna_def_nlastrip(BlenderRNA *brna) { - StructRNA *srna; - PropertyRNA *prop; - - /* enum defs */ - static const EnumPropertyItem prop_type_items[] = { - {NLASTRIP_TYPE_CLIP, "CLIP", 0, "Action Clip", "NLA Strip references some Action"}, - {NLASTRIP_TYPE_TRANSITION, "TRANSITION", 0, "Transition", "NLA Strip 'transitions' between adjacent strips"}, - {NLASTRIP_TYPE_META, "META", 0, "Meta", "NLA Strip acts as a container for adjacent strips"}, - {NLASTRIP_TYPE_SOUND, "SOUND", 0, "Sound Clip", "NLA Strip representing a sound event for speakers"}, - {0, NULL, 0, NULL, NULL}, - }; - - /* struct definition */ - srna = RNA_def_struct(brna, "NlaStrip", NULL); - RNA_def_struct_ui_text(srna, "NLA Strip", "A container referencing an existing Action"); - RNA_def_struct_path_func(srna, "rna_NlaStrip_path"); - RNA_def_struct_ui_icon(srna, ICON_NLA); /* XXX */ - - /* name property */ - prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); - RNA_def_property_ui_text(prop, "Name", ""); - RNA_def_property_string_funcs(prop, NULL, NULL, "rna_NlaStrip_name_set"); - RNA_def_struct_name_property(srna, prop); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */ - - /* Enums */ - prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "type"); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* XXX for now, not editable, since this is dangerous */ - RNA_def_property_enum_items(prop, prop_type_items); - RNA_def_property_ui_text(prop, "Type", "Type of NLA Strip"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); - - prop = RNA_def_property(srna, "extrapolation", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "extendmode"); - RNA_def_property_enum_items(prop, rna_enum_nla_mode_extend_items); - RNA_def_property_ui_text(prop, "Extrapolation", "Action to take for gaps past the strip extents"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); - - prop = RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "blendmode"); - RNA_def_property_enum_items(prop, rna_enum_nla_mode_blend_items); - RNA_def_property_ui_text(prop, "Blending", "Method used for combining strip's result with accumulated result"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); - - /* Strip extents */ - prop = RNA_def_property(srna, "frame_start", PROP_FLOAT, PROP_TIME); - RNA_def_property_float_sdna(prop, NULL, "start"); - RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_start_frame_set", NULL); - RNA_def_property_ui_text(prop, "Start Frame", ""); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); - - prop = RNA_def_property(srna, "frame_end", PROP_FLOAT, PROP_TIME); - RNA_def_property_float_sdna(prop, NULL, "end"); - RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_end_frame_set", NULL); - RNA_def_property_ui_text(prop, "End Frame", ""); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); - - /* Blending */ - prop = RNA_def_property(srna, "blend_in", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "blendin"); - RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_blend_in_set", NULL); - RNA_def_property_ui_text(prop, "Blend In", "Number of frames at start of strip to fade in influence"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); - - prop = RNA_def_property(srna, "blend_out", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "blendout"); - RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_blend_out_set", NULL); - RNA_def_property_ui_text(prop, "Blend Out", ""); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); - - prop = RNA_def_property(srna, "use_auto_blend", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_AUTO_BLENDS); - RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaStrip_use_auto_blend_set"); - RNA_def_property_ui_text(prop, "Auto Blend In/Out", - "Number of frames for Blending In/Out is automatically determined from " - "overlapping strips"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); - - /* Action */ - prop = RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE); - RNA_def_property_pointer_sdna(prop, NULL, "act"); - RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Action_id_poll"); - RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); - RNA_def_property_editable_func(prop, "rna_NlaStrip_action_editable"); - RNA_def_property_ui_text(prop, "Action", "Action referenced by this strip"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_dependency_update"); - - /* Action extents */ - prop = RNA_def_property(srna, "action_frame_start", PROP_FLOAT, PROP_TIME); - RNA_def_property_float_sdna(prop, NULL, "actstart"); - RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_action_start_frame_set", NULL); - RNA_def_property_ui_text(prop, "Action Start Frame", "First frame from action to use"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); - - prop = RNA_def_property(srna, "action_frame_end", PROP_FLOAT, PROP_TIME); - RNA_def_property_float_sdna(prop, NULL, "actend"); - RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_action_end_frame_set", NULL); - RNA_def_property_ui_text(prop, "Action End Frame", "Last frame from action to use"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); - - /* Action Reuse */ - prop = RNA_def_property(srna, "repeat", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "repeat"); - RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_repeat_set", NULL); - /* these limits have currently be chosen arbitrarily, but could be extended - * (minimum should still be > 0 though) if needed... */ - RNA_def_property_range(prop, 0.1f, 1000.0f); - RNA_def_property_ui_text(prop, "Repeat", "Number of times to repeat the action range"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); - - prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "scale"); - RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_scale_set", NULL); - /* these limits can be extended, but beyond this, we can get some crazy+annoying bugs - * due to numeric errors */ - RNA_def_property_range(prop, 0.0001f, 1000.0f); - RNA_def_property_ui_text(prop, "Scale", "Scaling factor for action"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); - - /* Strip's F-Curves */ - prop = RNA_def_property(srna, "fcurves", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "fcurves", NULL); - RNA_def_property_struct_type(prop, "FCurve"); - RNA_def_property_ui_text(prop, "F-Curves", "F-Curves for controlling the strip's influence and timing"); - rna_def_strip_fcurves(brna, prop); - - /* Strip's F-Modifiers */ - prop = RNA_def_property(srna, "modifiers", PROP_COLLECTION, PROP_NONE); - RNA_def_property_struct_type(prop, "FModifier"); - RNA_def_property_ui_text(prop, "Modifiers", "Modifiers affecting all the F-Curves in the referenced Action"); - - /* Strip's Sub-Strips (for Meta-Strips) */ - prop = RNA_def_property(srna, "strips", PROP_COLLECTION, PROP_NONE); - RNA_def_property_struct_type(prop, "NlaStrip"); - RNA_def_property_ui_text(prop, "NLA Strips", - "NLA Strips that this strip acts as a container for (if it is of type Meta)"); - - /* Settings - Values necessary for evaluation */ - prop = RNA_def_property(srna, "influence", PROP_FLOAT, PROP_FACTOR); - RNA_def_property_range(prop, 0.0f, 1.0f); - RNA_def_property_ui_text(prop, "Influence", "Amount the strip contributes to the current result"); - /* XXX: Update temporarily disabled so that the property can be edited at all! - * Even autokey only applies after the curves have been re-evaluated, causing the unkeyed values to be lost - */ - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, /*"rna_NlaStrip_update"*/ NULL); - - prop = RNA_def_property(srna, "strip_time", PROP_FLOAT, PROP_TIME); - RNA_def_property_ui_text(prop, "Strip Time", "Frame of referenced Action to evaluate"); - /* XXX: Update temporarily disabled so that the property can be edited at all! - * Even autokey only applies after the curves have been re-evaluated, causing the unkeyed values to be lost - */ - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, /*"rna_NlaStrip_update"*/ NULL); - - /* TODO: should the animated_influence/time settings be animatable themselves? */ - prop = RNA_def_property(srna, "use_animated_influence", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_INFLUENCE); - RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaStrip_animated_influence_set"); - RNA_def_property_ui_text(prop, "Animated Influence", - "Influence setting is controlled by an F-Curve rather than automatically determined"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); - - prop = RNA_def_property(srna, "use_animated_time", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_TIME); - RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaStrip_animated_time_set"); - RNA_def_property_ui_text(prop, "Animated Strip Time", - "Strip time is controlled by an F-Curve rather than automatically determined"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); - - prop = RNA_def_property(srna, "use_animated_time_cyclic", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_TIME_CYCLIC); - RNA_def_property_ui_text(prop, "Cyclic Strip Time", "Cycle the animated time within the action start & end"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); - - /* settings */ - prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE); - /* can be made editable by hooking it up to the necessary NLA API methods */ - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_ACTIVE); - RNA_def_property_ui_text(prop, "Active", "NLA Strip is active"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */ - - prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_SELECT); - RNA_def_property_ui_text(prop, "Select", "NLA Strip is selected"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */ - - prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_MUTED); - RNA_def_property_ui_text(prop, "Muted", "Disable NLA Strip evaluation"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); - - prop = RNA_def_property(srna, "use_reverse", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_REVERSE); - RNA_def_property_ui_text(prop, "Reversed", - "NLA Strip is played back in reverse order (only when timing is " - "automatically determined)"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); - - prop = RNA_def_property(srna, "use_sync_length", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_SYNC_LENGTH); - RNA_def_property_ui_text(prop, "Sync Action Length", - "Update range of frames referenced from action " - "after tweaking strip and its keyframes"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); + StructRNA *srna; + PropertyRNA *prop; + + /* enum defs */ + static const EnumPropertyItem prop_type_items[] = { + {NLASTRIP_TYPE_CLIP, "CLIP", 0, "Action Clip", "NLA Strip references some Action"}, + {NLASTRIP_TYPE_TRANSITION, + "TRANSITION", + 0, + "Transition", + "NLA Strip 'transitions' between adjacent strips"}, + {NLASTRIP_TYPE_META, "META", 0, "Meta", "NLA Strip acts as a container for adjacent strips"}, + {NLASTRIP_TYPE_SOUND, + "SOUND", + 0, + "Sound Clip", + "NLA Strip representing a sound event for speakers"}, + {0, NULL, 0, NULL, NULL}, + }; + + /* struct definition */ + srna = RNA_def_struct(brna, "NlaStrip", NULL); + RNA_def_struct_ui_text(srna, "NLA Strip", "A container referencing an existing Action"); + RNA_def_struct_path_func(srna, "rna_NlaStrip_path"); + RNA_def_struct_ui_icon(srna, ICON_NLA); /* XXX */ + + /* name property */ + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_ui_text(prop, "Name", ""); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_NlaStrip_name_set"); + RNA_def_struct_name_property(srna, prop); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */ + + /* Enums */ + prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "type"); + RNA_def_property_clear_flag( + prop, PROP_EDITABLE); /* XXX for now, not editable, since this is dangerous */ + RNA_def_property_enum_items(prop, prop_type_items); + RNA_def_property_ui_text(prop, "Type", "Type of NLA Strip"); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); + + prop = RNA_def_property(srna, "extrapolation", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "extendmode"); + RNA_def_property_enum_items(prop, rna_enum_nla_mode_extend_items); + RNA_def_property_ui_text( + prop, "Extrapolation", "Action to take for gaps past the strip extents"); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); + + prop = RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "blendmode"); + RNA_def_property_enum_items(prop, rna_enum_nla_mode_blend_items); + RNA_def_property_ui_text( + prop, "Blending", "Method used for combining strip's result with accumulated result"); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); + + /* Strip extents */ + prop = RNA_def_property(srna, "frame_start", PROP_FLOAT, PROP_TIME); + RNA_def_property_float_sdna(prop, NULL, "start"); + RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_start_frame_set", NULL); + RNA_def_property_ui_text(prop, "Start Frame", ""); + RNA_def_property_update( + prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); + + prop = RNA_def_property(srna, "frame_end", PROP_FLOAT, PROP_TIME); + RNA_def_property_float_sdna(prop, NULL, "end"); + RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_end_frame_set", NULL); + RNA_def_property_ui_text(prop, "End Frame", ""); + RNA_def_property_update( + prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); + + /* Blending */ + prop = RNA_def_property(srna, "blend_in", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "blendin"); + RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_blend_in_set", NULL); + RNA_def_property_ui_text( + prop, "Blend In", "Number of frames at start of strip to fade in influence"); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); + + prop = RNA_def_property(srna, "blend_out", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "blendout"); + RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_blend_out_set", NULL); + RNA_def_property_ui_text(prop, "Blend Out", ""); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); + + prop = RNA_def_property(srna, "use_auto_blend", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_AUTO_BLENDS); + RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaStrip_use_auto_blend_set"); + RNA_def_property_ui_text(prop, + "Auto Blend In/Out", + "Number of frames for Blending In/Out is automatically determined from " + "overlapping strips"); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); + + /* Action */ + prop = RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "act"); + RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Action_id_poll"); + RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT); + RNA_def_property_editable_func(prop, "rna_NlaStrip_action_editable"); + RNA_def_property_ui_text(prop, "Action", "Action referenced by this strip"); + RNA_def_property_update( + prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_dependency_update"); + + /* Action extents */ + prop = RNA_def_property(srna, "action_frame_start", PROP_FLOAT, PROP_TIME); + RNA_def_property_float_sdna(prop, NULL, "actstart"); + RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_action_start_frame_set", NULL); + RNA_def_property_ui_text(prop, "Action Start Frame", "First frame from action to use"); + RNA_def_property_update( + prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); + + prop = RNA_def_property(srna, "action_frame_end", PROP_FLOAT, PROP_TIME); + RNA_def_property_float_sdna(prop, NULL, "actend"); + RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_action_end_frame_set", NULL); + RNA_def_property_ui_text(prop, "Action End Frame", "Last frame from action to use"); + RNA_def_property_update( + prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); + + /* Action Reuse */ + prop = RNA_def_property(srna, "repeat", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "repeat"); + RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_repeat_set", NULL); + /* these limits have currently be chosen arbitrarily, but could be extended + * (minimum should still be > 0 though) if needed... */ + RNA_def_property_range(prop, 0.1f, 1000.0f); + RNA_def_property_ui_text(prop, "Repeat", "Number of times to repeat the action range"); + RNA_def_property_update( + prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); + + prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "scale"); + RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_scale_set", NULL); + /* these limits can be extended, but beyond this, we can get some crazy+annoying bugs + * due to numeric errors */ + RNA_def_property_range(prop, 0.0001f, 1000.0f); + RNA_def_property_ui_text(prop, "Scale", "Scaling factor for action"); + RNA_def_property_update( + prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); + + /* Strip's F-Curves */ + prop = RNA_def_property(srna, "fcurves", PROP_COLLECTION, PROP_NONE); + RNA_def_property_collection_sdna(prop, NULL, "fcurves", NULL); + RNA_def_property_struct_type(prop, "FCurve"); + RNA_def_property_ui_text( + prop, "F-Curves", "F-Curves for controlling the strip's influence and timing"); + rna_def_strip_fcurves(brna, prop); + + /* Strip's F-Modifiers */ + prop = RNA_def_property(srna, "modifiers", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "FModifier"); + RNA_def_property_ui_text( + prop, "Modifiers", "Modifiers affecting all the F-Curves in the referenced Action"); + + /* Strip's Sub-Strips (for Meta-Strips) */ + prop = RNA_def_property(srna, "strips", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "NlaStrip"); + RNA_def_property_ui_text( + prop, + "NLA Strips", + "NLA Strips that this strip acts as a container for (if it is of type Meta)"); + + /* Settings - Values necessary for evaluation */ + prop = RNA_def_property(srna, "influence", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text( + prop, "Influence", "Amount the strip contributes to the current result"); + /* XXX: Update temporarily disabled so that the property can be edited at all! + * Even autokey only applies after the curves have been re-evaluated, causing the unkeyed values to be lost + */ + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, /*"rna_NlaStrip_update"*/ NULL); + + prop = RNA_def_property(srna, "strip_time", PROP_FLOAT, PROP_TIME); + RNA_def_property_ui_text(prop, "Strip Time", "Frame of referenced Action to evaluate"); + /* XXX: Update temporarily disabled so that the property can be edited at all! + * Even autokey only applies after the curves have been re-evaluated, causing the unkeyed values to be lost + */ + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, /*"rna_NlaStrip_update"*/ NULL); + + /* TODO: should the animated_influence/time settings be animatable themselves? */ + prop = RNA_def_property(srna, "use_animated_influence", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_INFLUENCE); + RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaStrip_animated_influence_set"); + RNA_def_property_ui_text( + prop, + "Animated Influence", + "Influence setting is controlled by an F-Curve rather than automatically determined"); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); + + prop = RNA_def_property(srna, "use_animated_time", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_TIME); + RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaStrip_animated_time_set"); + RNA_def_property_ui_text( + prop, + "Animated Strip Time", + "Strip time is controlled by an F-Curve rather than automatically determined"); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); + + prop = RNA_def_property(srna, "use_animated_time_cyclic", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_USR_TIME_CYCLIC); + RNA_def_property_ui_text( + prop, "Cyclic Strip Time", "Cycle the animated time within the action start & end"); + RNA_def_property_update( + prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_transform_update"); + + /* settings */ + prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE); + /* can be made editable by hooking it up to the necessary NLA API methods */ + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_ACTIVE); + RNA_def_property_ui_text(prop, "Active", "NLA Strip is active"); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */ + + prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_SELECT); + RNA_def_property_ui_text(prop, "Select", "NLA Strip is selected"); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */ + + prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_MUTED); + RNA_def_property_ui_text(prop, "Muted", "Disable NLA Strip evaluation"); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); + + prop = RNA_def_property(srna, "use_reverse", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_REVERSE); + RNA_def_property_ui_text(prop, + "Reversed", + "NLA Strip is played back in reverse order (only when timing is " + "automatically determined)"); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); + + prop = RNA_def_property(srna, "use_sync_length", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NLASTRIP_FLAG_SYNC_LENGTH); + RNA_def_property_ui_text(prop, + "Sync Action Length", + "Update range of frames referenced from action " + "after tweaking strip and its keyframes"); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); } static void rna_api_nlatrack_strips(BlenderRNA *brna, PropertyRNA *cprop) { - StructRNA *srna; - PropertyRNA *parm; - FunctionRNA *func; - - RNA_def_property_srna(cprop, "NlaStrips"); - srna = RNA_def_struct(brna, "NlaStrips", NULL); - RNA_def_struct_sdna(srna, "NlaTrack"); - RNA_def_struct_ui_text(srna, "Nla Strips", "Collection of Nla Strips"); - - func = RNA_def_function(srna, "new", "rna_NlaStrip_new"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_CONTEXT | FUNC_USE_REPORTS); - RNA_def_function_ui_description(func, "Add a new Action-Clip strip to the track"); - parm = RNA_def_string(func, "name", "NlaStrip", 0, "", "Name for the NLA Strips"); - RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); - parm = RNA_def_int(func, "start", 0, INT_MIN, INT_MAX, "Start Frame", - "Start frame for this strip", INT_MIN, INT_MAX); - RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); - parm = RNA_def_pointer(func, "action", "Action", "", "Action to assign to this strip"); - RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); - /* return type */ - parm = RNA_def_pointer(func, "strip", "NlaStrip", "", "New NLA Strip"); - RNA_def_function_return(func, parm); - - func = RNA_def_function(srna, "remove", "rna_NlaStrip_remove"); - RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_CONTEXT | FUNC_USE_REPORTS); - RNA_def_function_ui_description(func, "Remove a NLA Strip"); - parm = RNA_def_pointer(func, "strip", "NlaStrip", "", "NLA Strip to remove"); - RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); - RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0); + StructRNA *srna; + PropertyRNA *parm; + FunctionRNA *func; + + RNA_def_property_srna(cprop, "NlaStrips"); + srna = RNA_def_struct(brna, "NlaStrips", NULL); + RNA_def_struct_sdna(srna, "NlaTrack"); + RNA_def_struct_ui_text(srna, "Nla Strips", "Collection of Nla Strips"); + + func = RNA_def_function(srna, "new", "rna_NlaStrip_new"); + RNA_def_function_flag(func, + FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_CONTEXT | FUNC_USE_REPORTS); + RNA_def_function_ui_description(func, "Add a new Action-Clip strip to the track"); + parm = RNA_def_string(func, "name", "NlaStrip", 0, "", "Name for the NLA Strips"); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_int(func, + "start", + 0, + INT_MIN, + INT_MAX, + "Start Frame", + "Start frame for this strip", + INT_MIN, + INT_MAX); + RNA_def_parameter_flags(parm, 0, PARM_REQUIRED); + parm = RNA_def_pointer(func, "action", "Action", "", "Action to assign to this strip"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED); + /* return type */ + parm = RNA_def_pointer(func, "strip", "NlaStrip", "", "New NLA Strip"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove", "rna_NlaStrip_remove"); + RNA_def_function_flag(func, + FUNC_USE_SELF_ID | FUNC_USE_MAIN | FUNC_USE_CONTEXT | FUNC_USE_REPORTS); + RNA_def_function_ui_description(func, "Remove a NLA Strip"); + parm = RNA_def_pointer(func, "strip", "NlaStrip", "", "NLA Strip to remove"); + RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED | PARM_RNAPTR); + RNA_def_parameter_clear_flags(parm, PROP_THICK_WRAP, 0); } static void rna_def_nlatrack(BlenderRNA *brna) { - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "NlaTrack", NULL); - RNA_def_struct_ui_text(srna, "NLA Track", "A animation layer containing Actions referenced as NLA strips"); - RNA_def_struct_ui_icon(srna, ICON_NLA); - - /* strips collection */ - prop = RNA_def_property(srna, "strips", PROP_COLLECTION, PROP_NONE); - RNA_def_property_struct_type(prop, "NlaStrip"); - RNA_def_property_ui_text(prop, "NLA Strips", "NLA Strips on this NLA-track"); - - rna_api_nlatrack_strips(brna, prop); - - /* name property */ - prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); - RNA_def_property_ui_text(prop, "Name", ""); - RNA_def_struct_name_property(srna, prop); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */ - - /* settings */ - prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE); - /* can be made editable by hooking it up to the necessary NLA API methods */ - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_ACTIVE); - RNA_def_property_ui_text(prop, "Active", "NLA Track is active"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */ - - prop = RNA_def_property(srna, "is_solo", PROP_BOOLEAN, PROP_NONE); - /* can be made editable by hooking it up to the necessary NLA API methods */ - RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_SOLO); - RNA_def_property_ui_text(prop, "Solo", - "NLA Track is evaluated itself (i.e. active Action and all other NLA Tracks in the " - "same AnimData block are disabled)"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); - RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaTrack_solo_set"); - - prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_SELECTED); - RNA_def_property_ui_text(prop, "Select", "NLA Track is selected"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */ - - prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_MUTED); - RNA_def_property_ui_text(prop, "Muted", "Disable NLA Track evaluation"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); - - prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_PROTECTED); - RNA_def_property_ui_text(prop, "Locked", "NLA Track is locked"); - RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */ + StructRNA *srna; + PropertyRNA *prop; + + srna = RNA_def_struct(brna, "NlaTrack", NULL); + RNA_def_struct_ui_text( + srna, "NLA Track", "A animation layer containing Actions referenced as NLA strips"); + RNA_def_struct_ui_icon(srna, ICON_NLA); + + /* strips collection */ + prop = RNA_def_property(srna, "strips", PROP_COLLECTION, PROP_NONE); + RNA_def_property_struct_type(prop, "NlaStrip"); + RNA_def_property_ui_text(prop, "NLA Strips", "NLA Strips on this NLA-track"); + + rna_api_nlatrack_strips(brna, prop); + + /* name property */ + prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); + RNA_def_property_ui_text(prop, "Name", ""); + RNA_def_struct_name_property(srna, prop); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */ + + /* settings */ + prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE); + /* can be made editable by hooking it up to the necessary NLA API methods */ + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_ACTIVE); + RNA_def_property_ui_text(prop, "Active", "NLA Track is active"); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */ + + prop = RNA_def_property(srna, "is_solo", PROP_BOOLEAN, PROP_NONE); + /* can be made editable by hooking it up to the necessary NLA API methods */ + RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_SOLO); + RNA_def_property_ui_text( + prop, + "Solo", + "NLA Track is evaluated itself (i.e. active Action and all other NLA Tracks in the " + "same AnimData block are disabled)"); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); + RNA_def_property_boolean_funcs(prop, NULL, "rna_NlaTrack_solo_set"); + + prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_SELECTED); + RNA_def_property_ui_text(prop, "Select", "NLA Track is selected"); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */ + + prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_MUTED); + RNA_def_property_ui_text(prop, "Muted", "Disable NLA Track evaluation"); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update"); + + prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", NLATRACK_PROTECTED); + RNA_def_property_ui_text(prop, "Locked", "NLA Track is locked"); + RNA_def_property_update(prop, NC_ANIMATION | ND_NLA, NULL); /* this will do? */ } /* --------- */ void RNA_def_nla(BlenderRNA *brna) { - rna_def_nlatrack(brna); - rna_def_nlastrip(brna); + rna_def_nlatrack(brna); + rna_def_nlastrip(brna); } - #endif |