diff options
author | Joshua Leung <aligorith@gmail.com> | 2011-06-29 08:34:20 +0400 |
---|---|---|
committer | Joshua Leung <aligorith@gmail.com> | 2011-06-29 08:34:20 +0400 |
commit | 2f60a5030f6c90c2278d3938460809de43012f85 (patch) | |
tree | fcf2b78b7a0c1e50cb613ad3219b94d06dc7f406 /source/blender/blenkernel/intern/action.c | |
parent | b85e0c3e850b8995577aee9b066e15e66c60bad3 (diff) |
Actions can now be made single-user from the Outliner
* Use the same method as from unlinking actions to do this.
* Split off the make single-user code used for the ID-browser into a
function in blenkernel which can be used elsewhere. Getting materials
to also work using this method proved to be a bit too tricky (due to
the whole messy ob vs obdata situation), so I haven't done that.
Diffstat (limited to 'source/blender/blenkernel/intern/action.c')
-rw-r--r-- | source/blender/blenkernel/intern/action.c | 88 |
1 files changed, 55 insertions, 33 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 08eed6d61ba..e69ff5df913 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -89,60 +89,80 @@ bAction *add_empty_action(const char name[]) return act; } +/* .................................. */ + +/* temp data for make_local_action */ +typedef struct tMakeLocalActionContext { + bAction *act; /* original action */ + bAction *actn; /* new action */ + + int lib; /* some action users were libraries */ + int local; /* some action users were not libraries */ +} tMakeLocalActionContext; + +/* helper function for make_local_action() - local/lib init step */ +static void make_localact_init_cb(ID *id, AnimData *adt, void *mlac_ptr) +{ + tMakeLocalActionContext *mlac = (tMakeLocalActionContext *)mlac_ptr; + + if (adt->action == mlac->act) { + if (id->lib) + mlac->lib = 1; + else + mlac->local = 1; + } +} + +/* helper function for make_local_action() - change references */ +static void make_localact_apply_cb(ID *id, AnimData *adt, void *mlac_ptr) +{ + tMakeLocalActionContext *mlac = (tMakeLocalActionContext *)mlac_ptr; + + if (adt->action == mlac->act) { + if (id->lib==0) { + adt->action = mlac->actn; + + id_us_plus(&mlac->actn->id); + id_us_min(&mlac->act->id); + } + } +} + // does copy_fcurve... void make_local_action(bAction *act) { - // Object *ob; + tMakeLocalActionContext mlac = {act, NULL, 0, 0}; Main *bmain= G.main; - bAction *actn; - int local=0, lib=0; - if (act->id.lib==NULL) return; - if (act->id.us==1) { + if (act->id.lib==NULL) + return; + + // XXX: double-check this; it used to be just single-user check, but that was when fake-users were still default + if ((act->id.flag & LIB_FAKEUSER) && (act->id.us<=1)) { act->id.lib= NULL; act->id.flag= LIB_LOCAL; new_id(&bmain->action, (ID *)act, NULL); return; } -#if 0 // XXX old animation system - ob= G.main->object.first; - while(ob) { - if(ob->action==act) { - if(ob->id.lib) lib= 1; - else local= 1; - } - ob= ob->id.next; - } -#endif + BKE_animdata_main_cb(bmain, make_localact_init_cb, &mlac); - if(local && lib==0) { + if (mlac.local && mlac.lib==0) { act->id.lib= NULL; act->id.flag= LIB_LOCAL; //make_local_action_channels(act); new_id(&bmain->action, (ID *)act, NULL); } - else if(local && lib) { - actn= copy_action(act); - actn->id.us= 0; + else if (mlac.local && mlac.lib) { + mlac.actn= copy_action(act); + mlac.actn->id.us= 0; -#if 0 // XXX old animation system - ob= G.main->object.first; - while(ob) { - if(ob->action==act) { - - if(ob->id.lib==0) { - ob->action = actn; - actn->id.us++; - act->id.us--; - } - } - ob= ob->id.next; - } -#endif // XXX old animation system + BKE_animdata_main_cb(bmain, make_localact_apply_cb, &mlac); } } +/* .................................. */ + void free_action (bAction *act) { /* sanity check */ @@ -161,6 +181,8 @@ void free_action (bAction *act) BLI_freelistN(&act->markers); } +/* .................................. */ + bAction *copy_action (bAction *src) { bAction *dst = NULL; |