edits ontop of Alex's patch from r41292.
[blender.git] / source / blender / blenkernel / intern / action.c
index f7086c8..d02a1d6 100644 (file)
@@ -1,6 +1,4 @@
 /*
- * $Id$
- *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
@@ -85,66 +83,79 @@ bAction *add_empty_action(const char name[])
        bAction *act;
        
        act= alloc_libblock(&G.main->action, ID_AC, name);
-       act->id.flag |= LIB_FAKEUSER; // XXX this is nasty for new users... maybe we don't want this anymore
-       act->id.us++;
        
        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 == NULL) {
+                       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) {
-               act->id.lib= NULL;
-               act->id.flag= LIB_LOCAL;
-               new_id(&bmain->action, (ID *)act, NULL);
+       
+       if (act->id.lib==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;
+       // 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)) {
+               id_clear_lib_data(bmain, (ID *)act);
+               return;
        }
-#endif
        
-       if(local && lib==0) {
-               act->id.lib= NULL;
-               act->id.flag= LIB_LOCAL;
-               //make_local_action_channels(act);
-               new_id(&bmain->action, (ID *)act, NULL);
+       BKE_animdata_main_cb(bmain, make_localact_init_cb, &mlac);
+       
+       if (mlac.local && mlac.lib==0) {
+               id_clear_lib_data(bmain, (ID *)act);
        }
-       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 */
@@ -163,6 +174,8 @@ void free_action (bAction *act)
                BLI_freelistN(&act->markers);
 }
 
+/* .................................. */
+
 bAction *copy_action (bAction *src)
 {
        bAction *dst = NULL;
@@ -200,9 +213,6 @@ bAction *copy_action (bAction *src)
                }
        }
        
-       dst->id.flag |= LIB_FAKEUSER; // XXX this is nasty for new users... maybe we don't want this anymore
-       dst->id.us++;
-       
        return dst;
 }
 
@@ -255,7 +265,7 @@ bActionGroup *action_groups_add_new (bAction *act, const char name[])
        
        /* make it selected, with default name */
        agrp->flag = AGRP_SELECTED;
-       strncpy(agrp->name, name[0] ? name : "Group", sizeof(agrp->name));
+       BLI_strncpy(agrp->name, name[0] ? name : "Group", sizeof(agrp->name));
        
        /* add to action, and validate */
        BLI_addtail(&act->groups, agrp);
@@ -509,7 +519,6 @@ void copy_pose (bPose **dst, bPose *src, int copycon)
                if (copycon) {
                        copy_constraints(&listb, &pchan->constraints, TRUE);  // copy_constraints NULLs listb
                        pchan->constraints= listb;
-                       pchan->path= NULL; // XXX remove this line when the new motionpaths are ready... (depreceated code)
                        pchan->mpath= NULL; /* motion paths should not get copied yet... */
                }
                
@@ -580,17 +589,12 @@ void free_pose_channels_hash(bPose *pose)
 
 void free_pose_channel(bPoseChannel *pchan)
 {
-       // XXX this case here will need to be removed when the new motionpaths are ready
-       if (pchan->path) {
-               MEM_freeN(pchan->path);
-               pchan->path= NULL;
-       }
-       
+
        if (pchan->mpath) {
                animviz_free_motionpath(pchan->mpath);
                pchan->mpath= NULL;
        }
-       
+
        free_constraints(&pchan->constraints);
        
        if (pchan->prop) {
@@ -872,7 +876,7 @@ void calc_action_range(const bAction *act, float *start, float *end, short incl_
                                
                                /* get extents for this curve */
                                // TODO: allow enabling/disabling this?
-                               calc_fcurve_range(fcu, &nmin, &nmax, FALSE);
+                               calc_fcurve_range(fcu, &nmin, &nmax, FALSE, TRUE);
                                
                                /* compare to the running tally */
                                min= MIN2(min, nmin);
@@ -1180,7 +1184,7 @@ void what_does_obaction (Object *ob, Object *workob, bPose *pose, bAction *act,
                adt.action= act;
                
                /* execute effects of Action on to workob (or it's PoseChannels) */
-               BKE_animsys_evaluate_animdata(&workob->id, &adt, cframe, ADT_RECALC_ANIM);
+               BKE_animsys_evaluate_animdata(NULL, &workob->id, &adt, cframe, ADT_RECALC_ANIM);
        }
 }