diff options
-rw-r--r-- | source/blender/blenkernel/BKE_nla.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/nla.c | 93 | ||||
-rw-r--r-- | source/blender/editors/space_nla/nla_buttons.c | 3 | ||||
-rw-r--r-- | source/blender/editors/space_nla/nla_draw.c | 25 | ||||
-rw-r--r-- | source/blender/editors/space_nla/nla_edit.c | 31 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_anim_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_nla.c | 22 |
7 files changed, 152 insertions, 28 deletions
diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h index 04d4b0f8da2..bb5a2782663 100644 --- a/source/blender/blenkernel/BKE_nla.h +++ b/source/blender/blenkernel/BKE_nla.h @@ -83,6 +83,10 @@ struct NlaStrip *BKE_nlastrip_find_active(struct NlaTrack *nlt); short BKE_nlastrip_within_bounds(struct NlaStrip *strip, float min, float max); +void BKE_nlastrip_validate_name(struct AnimData *adt, struct NlaStrip *strip); + +/* ............ */ + short BKE_nlatrack_has_animated_strips(struct NlaTrack *nlt); short BKE_nlatracks_have_animated_strips(ListBase *tracks); void BKE_nlastrip_validate_fcurves(struct NlaStrip *strip); diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c index c697f639021..a240de209d9 100644 --- a/source/blender/blenkernel/intern/nla.c +++ b/source/blender/blenkernel/intern/nla.c @@ -30,12 +30,14 @@ #include <stdlib.h> #include <stddef.h> #include <stdio.h> +#include <string.h> #include <math.h> #include <float.h> #include "MEM_guardedalloc.h" #include "BLI_blenlib.h" +#include "BLI_ghash.h" #include "DNA_anim_types.h" #include "DNA_action_types.h" @@ -326,6 +328,9 @@ NlaStrip *add_nlastrip_to_stack (AnimData *adt, bAction *act) BKE_nlatrack_add_strip(nlt, strip); } + /* automatically name it too */ + BKE_nlastrip_validate_name(adt, strip); + /* returns the strip added */ return strip; } @@ -503,7 +508,7 @@ float BKE_nla_tweakedit_remap (AnimData *adt, float cframe, short mode) } /* *************************************************** */ -/* Basic Utilities */ +/* NLA API */ /* List of Strips ------------------------------------ */ /* (these functions are used for NLA-Tracks and also for nested/meta-strips) */ @@ -1140,8 +1145,90 @@ void BKE_nlastrip_validate_fcurves (NlaStrip *strip) } } } - -/* Tools ------------------------------------------- */ + +/* Sanity Validation ------------------------------------ */ + +/* Find (and set) a unique name for a strip from the whole AnimData block + * Uses a similar method to the BLI method, but is implemented differently + * as we need to ensure that the name is unique over several lists of tracks, + * not just a single track. + */ +void BKE_nlastrip_validate_name (AnimData *adt, NlaStrip *strip) +{ + GHash *gh; + NlaStrip *tstrip; + NlaTrack *nlt; + + /* sanity checks */ + if ELEM(NULL, adt, strip) + return; + + /* give strip a default name if none already */ + if (strip->name[0]==0) { + switch (strip->type) { + case NLASTRIP_TYPE_CLIP: /* act-clip */ + sprintf(strip->name, "Act: %s", (strip->act)?(strip->act->id.name+2):("<None>")); + break; + case NLASTRIP_TYPE_TRANSITION: /* transition */ + sprintf(strip->name, "Transition"); + break; + case NLASTRIP_TYPE_META: /* meta */ + sprintf(strip->name, "Meta"); + break; + default: + sprintf(strip->name, "NLA Strip"); + break; + } + } + + /* build a hash-table of all the strips in the tracks + * - this is easier than iterating over all the tracks+strips hierarchy everytime + * (and probably faster) + */ + gh= BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp); + + for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) { + for (tstrip= nlt->strips.first; tstrip; tstrip= tstrip->next) { + /* don't add the strip of interest */ + if (tstrip == strip) + continue; + + /* use the name of the strip as the key, and the strip as the value, since we're mostly interested in the keys */ + BLI_ghash_insert(gh, tstrip->name, tstrip); + } + } + + /* if the hash-table has a match for this name, try other names... + * - in an extreme case, it might not be able to find a name, but then everything else in Blender would fail too :) + */ + if (BLI_ghash_haskey(gh, strip->name)) { + char tempname[128]; + int number = 1; + char *dot; + + /* Strip off the suffix */ + dot = strchr(strip->name, '.'); + if (dot) *dot=0; + + /* Try different possibilities */ + for (number = 1; number <= 999; number++) { + /* assemble alternative name */ + BLI_snprintf(tempname, 128, "%s%c%03d", strip->name, ".", number); + + /* if hash doesn't have this, set it */ + if (BLI_ghash_haskey(gh, tempname) == 0) { + BLI_strncpy(strip->name, tempname, sizeof(strip->name)); + break; + } + } + } + + /* free the hash... */ + BLI_ghash_free(gh, NULL, NULL); +} + + +/* Core Tools ------------------------------------------- */ /* For the given AnimData block, add the active action to the NLA * stack (i.e. 'push-down' action). The UI should only allow this diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c index c0a2b9476e3..a74037d1ace 100644 --- a/source/blender/editors/space_nla/nla_buttons.c +++ b/source/blender/editors/space_nla/nla_buttons.c @@ -215,7 +215,8 @@ static void nla_panel_properties(const bContext *C, Panel *pa) /* Strip Properties ------------------------------------- */ /* strip type */ - row= uiLayoutRow(layout, 1); + row= uiLayoutColumn(layout, 1); + uiItemR(row, NULL, ICON_NLA, &strip_ptr, "name", 0, 0, 0); // XXX icon? uiItemR(row, NULL, 0, &strip_ptr, "type", 0, 0, 0); /* strip extents */ diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index 7fb15c62277..8d56670a149 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -445,26 +445,11 @@ static void nla_draw_strip_text (NlaTrack *nlt, NlaStrip *strip, int index, View else sprintf(dir, "->"); - /* for now, just init the string with fixed-formats */ - switch (strip->type) { - case NLASTRIP_TYPE_TRANSITION: /* Transition */ - sprintf(str, "%d | Transition | %.2f %s %.2f", - index, strip->start, dir, strip->end); - break; - - case NLASTRIP_TYPE_META: /* Meta */ - sprintf(str, "%d | %sMeta | %.2f %s %.2f", - index, ((strip->flag & NLASTRIP_FLAG_TEMP_META)?"Temp-":""), - strip->start, dir, strip->end); - break; - - case NLASTRIP_TYPE_CLIP: /* Action-Clip (default) */ - default: - sprintf(str, "%d | Act: %s | %.2f %s %.2f", - index, ((strip->act)?strip->act->id.name+2:"<NONE>"), - strip->start, dir, strip->end); - break; - } + /* just print the name and the range */ + if (strip->flag & NLASTRIP_FLAG_TEMP_META) + sprintf(str, "Temp-Meta | %.2f %s %.2f", strip->start, dir, strip->end); + else + sprintf(str, "%s | %.2f %s %.2f", strip->name, strip->start, dir, strip->end); /* set text colour - if colours (see above) are light, draw black text, otherwise draw white */ if (strip->flag & (NLASTRIP_FLAG_ACTIVE|NLASTRIP_FLAG_SELECT|NLASTRIP_FLAG_TWEAKUSER)) diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index cb151429dd1..9ddd8daab0d 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -307,6 +307,9 @@ static int nlaedit_add_actionclip_exec (bContext *C, wmOperator *op) nlt= add_nlatrack(adt, NULL); BKE_nlatrack_add_strip(nlt, strip); } + + /* auto-name it */ + BKE_nlastrip_validate_name(adt, strip); } /* free temp data */ @@ -363,6 +366,7 @@ static int nlaedit_add_transition_exec (bContext *C, wmOperator *op) /* for each track, find pairs of strips to add transitions to */ for (ale= anim_data.first; ale; ale= ale->next) { NlaTrack *nlt= (NlaTrack *)ale->data; + AnimData *adt= BKE_animdata_from_id(ale->id); NlaStrip *s1, *s2; /* get initial pair of strips */ @@ -410,6 +414,9 @@ static int nlaedit_add_transition_exec (bContext *C, wmOperator *op) strip->scale= 1.0f; strip->repeat = 1.0f; + /* auto-name it */ + BKE_nlastrip_validate_name(adt, strip); + /* make note of this */ done++; } @@ -470,9 +477,18 @@ static int nlaedit_add_meta_exec (bContext *C, wmOperator *op) /* for each track, find pairs of strips to add transitions to */ for (ale= anim_data.first; ale; ale= ale->next) { NlaTrack *nlt= (NlaTrack *)ale->data; + AnimData *adt= BKE_animdata_from_id(ale->id); + NlaStrip *strip; /* create meta-strips from the continuous chains of selected strips */ BKE_nlastrips_make_metas(&nlt->strips, 0); + + /* name the metas */ + for (strip= nlt->strips.first; strip; strip= strip->next) { + /* auto-name this strip if selected (that means it is a meta) */ + if (strip->flag & NLASTRIP_FLAG_SELECT) + BKE_nlastrip_validate_name(adt, strip); + } } /* free temp data */ @@ -605,6 +621,9 @@ static int nlaedit_duplicate_exec (bContext *C, wmOperator *op) /* deselect the original and the active flag */ strip->flag &= ~(NLASTRIP_FLAG_SELECT|NLASTRIP_FLAG_ACTIVE); + /* auto-name it */ + BKE_nlastrip_validate_name(adt, strip); + done++; } } @@ -728,7 +747,7 @@ void NLA_OT_delete (wmOperatorType *ot) // - variable-length splits? /* split a given Action-Clip strip */ -static void nlaedit_split_strip_actclip (NlaTrack *nlt, NlaStrip *strip) +static void nlaedit_split_strip_actclip (AnimData *adt, NlaTrack *nlt, NlaStrip *strip) { NlaStrip *nstrip; float midframe, midaframe, len; @@ -765,10 +784,13 @@ static void nlaedit_split_strip_actclip (NlaTrack *nlt, NlaStrip *strip) /* clear the active flag from the copy */ nstrip->flag &= ~NLASTRIP_FLAG_ACTIVE; + + /* auto-name the new strip */ + BKE_nlastrip_validate_name(adt, nstrip); } /* split a given Meta strip */ -static void nlaedit_split_strip_meta (NlaTrack *nlt, NlaStrip *strip) +static void nlaedit_split_strip_meta (AnimData *adt, NlaTrack *nlt, NlaStrip *strip) { /* simply ungroup it for now... */ BKE_nlastrips_clear_metastrip(&nlt->strips, strip); @@ -795,6 +817,7 @@ static int nlaedit_split_exec (bContext *C, wmOperator *op) /* for each NLA-Track, split all selected strips into two strips */ for (ale= anim_data.first; ale; ale= ale->next) { NlaTrack *nlt= (NlaTrack *)ale->data; + AnimData *adt= BKE_animdata_from_id(ale->id); NlaStrip *strip, *next; for (strip= nlt->strips.first; strip; strip= next) { @@ -805,11 +828,11 @@ static int nlaedit_split_exec (bContext *C, wmOperator *op) /* splitting method depends on the type of strip */ switch (strip->type) { case NLASTRIP_TYPE_CLIP: /* action-clip */ - nlaedit_split_strip_actclip(nlt, strip); + nlaedit_split_strip_actclip(adt, nlt, strip); break; case NLASTRIP_TYPE_META: /* meta-strips need special handling */ - nlaedit_split_strip_meta(nlt, strip); + nlaedit_split_strip_meta(adt, nlt, strip); break; default: /* for things like Transitions, do not split! */ diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h index d71beb8785b..fed0c490014 100644 --- a/source/blender/makesdna/DNA_anim_types.h +++ b/source/blender/makesdna/DNA_anim_types.h @@ -445,6 +445,8 @@ typedef struct NlaStrip { ListBase fcurves; /* F-Curves for controlling this strip's influence and timing */ // TODO: move out? ListBase modifiers; /* F-Curve modifiers to be applied to the entire strip's referenced F-Curves */ + char name[64]; /* User-Visible Identifier for Strip */ + float influence; /* Influence of strip */ float strip_time; /* Current 'time' within action being used (automatically evaluated, but can be overridden) */ diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index 97f35af1db7..bc636af6849 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -41,11 +41,27 @@ #include <math.h> /* needed for some of the validation stuff... */ +#include "BKE_animsys.h" #include "BKE_nla.h" /* temp constant defined for these funcs only... */ #define NLASTRIP_MIN_LEN_THRESH 0.1f +void rna_NlaStrip_name_set(PointerRNA *ptr, const char *value) +{ + NlaStrip *data= (NlaStrip *)ptr->data; + + /* copy the name first */ + BLI_strncpy(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); + } +} + + static void rna_NlaStrip_start_frame_set(PointerRNA *ptr, float value) { NlaStrip *data= (NlaStrip*)ptr->data; @@ -255,6 +271,12 @@ void rna_def_nlastrip(BlenderRNA *brna) RNA_def_struct_ui_text(srna, "NLA Strip", "A container referencing an existing Action."); 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); + /* Enums */ prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "type"); |