2.5 - Keyframing Bugfixes + Code Cleanups
authorJoshua Leung <aligorith@gmail.com>
Fri, 4 Sep 2009 04:27:06 +0000 (04:27 +0000)
committerJoshua Leung <aligorith@gmail.com>
Fri, 4 Sep 2009 04:27:06 +0000 (04:27 +0000)
* DopeSheet + Graph Editor - 'Sample Keyframes' option now tags newly created keyframes as being breakdowns. Also moved reduced the code duplication here by moving the core code for this to the animation module.

* Keyframing (Standard/Auto) - Added proper 'replace' option
Keyframes can now be rekeyed non-destructively when the INSERTKEY_REPLACE flag is provided to the keyframing API functions, since this option will make sure that only the values of the handles get altered.

For the Auto-Keyframing 'Replace/Edit Keys' option, this means that it truly works as it describes now, since it will now only replace the values of the keyframes on the current frame, and won't create new keyframes in the process or destroy the tangents already created for those keys.

For things like the sliders in animation editors, keyframes changing the value won't destroy existing tangents.

12 files changed:
source/blender/editors/animation/anim_channels_defines.c
source/blender/editors/animation/keyframes_general.c
source/blender/editors/animation/keyframing.c
source/blender/editors/animation/keyingsets.c
source/blender/editors/include/ED_keyframes_draw.h
source/blender/editors/include/ED_keyframes_edit.h
source/blender/editors/include/ED_keyframing.h
source/blender/editors/interface/interface_anim.c
source/blender/editors/space_action/action_edit.c
source/blender/editors/space_action/action_header.c
source/blender/editors/space_graph/graph_edit.c
source/blender/editors/transform/transform_conversions.c

index b16420a70948cafbdab87ba496e08a9baee1baf6..e3418fa194ff5e62e758371d227a184d1e0cfeb3 100644 (file)
@@ -2003,6 +2003,8 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
                flag |= INSERTKEY_NEEDED;
        if (IS_AUTOKEY_FLAG(AUTOMATKEY))
                flag |= INSERTKEY_MATRIX;
+       if (IS_AUTOKEY_MODE(scene, EDITKEYS))
+               flag |= INSERTKEY_REPLACE;
        
        
        /* get RNA pointer, and resolve the path */
@@ -2010,6 +2012,10 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
        
        /* try to resolve the path stored in the F-Curve */
        if (RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) {
+               /* set the special 'replace' flag if on a keyframe */
+               if (fcurve_frame_has_keyframe(fcu, cfra, 0))
+                       flag |= INSERTKEY_REPLACE;
+               
                /* insert a keyframe for this F-Curve */
                done= insert_keyframe_direct(ptr, prop, fcu, cfra, flag);
                
index ced3c1177005e7447e265c27b7a6792b27487e69..f13d35c7d4a4bfe089cc0cd3205d9e175f5361bc 100644 (file)
@@ -357,6 +357,76 @@ void smooth_fcurve (FCurve *fcu)
        calchandles_fcurve(fcu);
 }
 
+/* ---------------- */
+
+/* little cache for values... */
+typedef struct tempFrameValCache {
+       float frame, val;
+} tempFrameValCache;
+
+
+/* Evaluates the curves between each selected keyframe on each frame, and keys the value  */
+void sample_fcurve (FCurve *fcu)
+{
+       BezTriple *bezt, *start=NULL, *end=NULL;
+       tempFrameValCache *value_cache, *fp;
+       int sfra, range;
+       int i, n, nIndex;
+       
+       /* find selected keyframes... once pair has been found, add keyframes  */
+       for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
+               /* check if selected, and which end this is */
+               if (BEZSELECTED(bezt)) {
+                       if (start) {
+                               /* set end */
+                               end= bezt;
+                               
+                               /* cache values then add keyframes using these values, as adding
+                                * keyframes while sampling will affect the outcome...
+                                *      - only start sampling+adding from index=1, so that we don't overwrite original keyframe
+                                */
+                               range= (int)( ceil(end->vec[1][0] - start->vec[1][0]) );
+                               sfra= (int)( floor(start->vec[1][0]) );
+                               
+                               if (range) {
+                                       value_cache= MEM_callocN(sizeof(tempFrameValCache)*range, "IcuFrameValCache");
+                                       
+                                       /*      sample values   */
+                                       for (n=1, fp=value_cache; n<range && fp; n++, fp++) {
+                                               fp->frame= (float)(sfra + n);
+                                               fp->val= evaluate_fcurve(fcu, fp->frame);
+                                       }
+                                       
+                                       /*      add keyframes with these, tagging as 'breakdowns'       */
+                                       for (n=1, fp=value_cache; n<range && fp; n++, fp++) {
+                                               nIndex= insert_vert_fcurve(fcu, fp->frame, fp->val, 1);
+                                               BEZKEYTYPE(fcu->bezt + nIndex)= BEZT_KEYTYPE_BREAKDOWN;
+                                       }
+                                       
+                                       /* free temp cache */
+                                       MEM_freeN(value_cache);
+                                       
+                                       /* as we added keyframes, we need to compensate so that bezt is at the right place */
+                                       bezt = fcu->bezt + i + range - 1;
+                                       i += (range - 1);
+                               }
+                               
+                               /* bezt was selected, so it now marks the start of a whole new chain to search */
+                               start= bezt;
+                               end= NULL;
+                       }
+                       else {
+                               /* just set start keyframe */
+                               start= bezt;
+                               end= NULL;
+                       }
+               }
+       }
+       
+       /* recalculate channel's handles? */
+       calchandles_fcurve(fcu);
+}
+
 /* **************************************************** */
 /* Copy/Paste Tools */
 /* - The copy/paste buffer currently stores a set of temporary F-Curves containing only the keyframes 
@@ -529,8 +599,10 @@ short paste_animedit_keys (bAnimContext *ac, ListBase *anim_data)
                                bezt->vec[1][0] += offset;
                                bezt->vec[2][0] += offset;
                                
-                               /* insert the keyframe */
-                               insert_bezt_fcurve(fcu, bezt);
+                               /* insert the keyframe
+                                * NOTE: no special flags here for now
+                                */
+                               insert_bezt_fcurve(fcu, bezt, 0); 
                                
                                /* un-apply offset from src beztriple after copying */
                                bezt->vec[0][0] -= offset;
index 5f444609baaacc33200047be7fd0b4de9a659223..d731ec6f148e496dc8aaea4a36e696c3b0d2d916 100644 (file)
@@ -262,9 +262,8 @@ static int binarysearch_bezt_index (BezTriple array[], float frame, int arraylen
  * NOTE: any recalculate of the F-Curve that needs to be done will need to 
  *             be done by the caller.
  */
-int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt)
+int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt, short flag)
 {
-       BezTriple *newb;
        int i= 0;
        
        if (fcu->bezt) {
@@ -273,13 +272,34 @@ int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt)
                
                if (replace) {                  
                        /* sanity check: 'i' may in rare cases exceed arraylen */
-                       // FIXME: do not overwrite handletype if just replacing...?
-                       if ((i >= 0) && (i < fcu->totvert))
-                               *(fcu->bezt + i) = *bezt;
+                       if ((i >= 0) && (i < fcu->totvert)) {
+                               /* take care with the handletypes and other info if the replacement flags are set */
+                               if (flag & INSERTKEY_REPLACE) {
+                                       BezTriple *dst= (fcu->bezt + i);
+                                       float dy= bezt->vec[1][1] - dst->vec[1][1];
+                                       
+                                       /* just apply delta value change to the handle values */
+                                       dst->vec[0][1] += dy;
+                                       dst->vec[1][1] += dy;
+                                       dst->vec[2][1] += dy;
+                                       
+                                       // TODO: perform some other operations?
+                               }
+                               else {
+                                       /* just brutally replace the values */
+                                       *(fcu->bezt + i) = *bezt;
+                               }
+                       }
                }
-               else {
-                       /* add new */
-                       newb= MEM_callocN((fcu->totvert+1)*sizeof(BezTriple), "beztriple");
+               else if ((flag & INSERTKEY_REPLACE) == 0) {
+                       /* add new - if we're not restricted to replacing keyframes only */
+                       BezTriple *newb;
+                       
+                       /* allocate a new array only if we have to */
+                       if ((flag & INSERTKEY_FASTR) == 0)
+                               newb= MEM_callocN((fcu->totvert+1)*sizeof(BezTriple), "beztriple");
+                       else
+                               newb= fcu->bezt;
                        
                        /* add the beztriples that should occur before the beztriple to be pasted (originally in ei->icu) */
                        if (i > 0)
@@ -292,9 +312,11 @@ int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt)
                        if (i < fcu->totvert) 
                                memcpy(newb+i+1, fcu->bezt+i, (fcu->totvert-i)*sizeof(BezTriple));
                        
-                       /* replace (+ free) old with new */
-                       MEM_freeN(fcu->bezt);
-                       fcu->bezt= newb;
+                       /* replace (+ free) old with new, only if necessary to do so */
+                       if ((flag & INSERTKEY_FASTR) == 0) {
+                               MEM_freeN(fcu->bezt);
+                               fcu->bezt= newb;
+                       }
                        
                        fcu->totvert++;
                }
@@ -313,13 +335,11 @@ int insert_bezt_fcurve (FCurve *fcu, BezTriple *bezt)
        return i;
 }
 
-/* This function is a wrapper for insert_bezt_icu, and should be used when
- * adding a new keyframe to a curve, when the keyframe doesn't exist anywhere
- * else yet. 
- * 
- * 'fast' - is only for the python API where importing BVH's would take an extreamly long time.
+/* This function is a wrapper for insert_bezt_fcurve_internal(), and should be used when
+ * adding a new keyframe to a curve, when the keyframe doesn't exist anywhere else yet. 
+ * It returns the index at which the keyframe was added.
  */
-void insert_vert_fcurve (FCurve *fcu, float x, float y, short fast)
+int insert_vert_fcurve (FCurve *fcu, float x, float y, short flag)
 {
        BezTriple beztr;
        int a;
@@ -337,21 +357,22 @@ void insert_vert_fcurve (FCurve *fcu, float x, float y, short fast)
        beztr.h1= beztr.h2= HD_AUTO; // XXX what about when we replace an old one?
        
        /* add temp beztriple to keyframes */
-       a= insert_bezt_fcurve(fcu, &beztr);
+       a= insert_bezt_fcurve(fcu, &beztr, flag);
        
        /* what if 'a' is a negative index? 
         * for now, just exit to prevent any segfaults
         */
-       if (a < 0) return;
+       if (a < 0) return -1;
        
        /* don't recalculate handles if fast is set
         *      - this is a hack to make importers faster
-        *      - we may calculate twice (see editipo_changed(), due to autohandle needing two calculations)
+        *      - we may calculate twice (due to autohandle needing to be calculated twice)
         */
-       if (!fast) calchandles_fcurve(fcu);
+       if ((flag & INSERTKEY_FAST) == 0) 
+               calchandles_fcurve(fcu);
        
        /* set handletype and interpolation */
-       if (fcu->totvert > 2) {
+       if ((fcu->totvert > 2) && (flag & INSERTKEY_REPLACE)==0) {
                BezTriple *bezt= (fcu->bezt + a);
                char h1, h2;
                
@@ -370,10 +391,14 @@ void insert_vert_fcurve (FCurve *fcu, float x, float y, short fast)
                        
                /* don't recalculate handles if fast is set
                 *      - this is a hack to make importers faster
-                *      - we may calculate twice (see editipo_changed(), due to autohandle needing two calculations)
+                *      - we may calculate twice (due to autohandle needing to be calculated twice)
                 */
-               if (!fast) calchandles_fcurve(fcu);
+               if ((flag & INSERTKEY_FAST) == 0) 
+                       calchandles_fcurve(fcu);
        }
+       
+       /* return the index at which the keyframe was added */
+       return a;
 }
 
 /* -------------- 'Smarter' Keyframing Functions -------------------- */
@@ -812,7 +837,7 @@ short insert_keyframe_direct (PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, fl
                
                /* insert new keyframe at current frame */
                if (insert_mode)
-                       insert_vert_fcurve(fcu, cfra, curval, (flag & INSERTKEY_FAST));
+                       insert_vert_fcurve(fcu, cfra, curval, flag);
                
                /* delete keyframe immediately before/after newly added */
                switch (insert_mode) {
@@ -830,7 +855,7 @@ short insert_keyframe_direct (PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, fl
        }
        else {
                /* just insert keyframe */
-               insert_vert_fcurve(fcu, cfra, curval, (flag & INSERTKEY_FAST));
+               insert_vert_fcurve(fcu, cfra, curval, flag);
                
                /* return success */
                return 1;
@@ -1303,6 +1328,15 @@ static int insert_key_button_exec (bContext *C, wmOperator *op)
        float cfra= (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
        short success= 0;
        int a, index, length, all= RNA_boolean_get(op->ptr, "all");
+       short flag = 0;
+       
+       /* flags for inserting keyframes */
+       if (IS_AUTOKEY_FLAG(AUTOMATKEY))
+               flag |= INSERTKEY_MATRIX;
+       if (IS_AUTOKEY_FLAG(INSERTNEEDED))
+               flag |= INSERTKEY_NEEDED;
+       if (IS_AUTOKEY_MODE(scene, EDITKEYS))
+               flag |= INSERTKEY_REPLACE;
        
        /* try to insert keyframe using property retrieved from UI */
        memset(&ptr, 0, sizeof(PointerRNA));
@@ -1322,14 +1356,14 @@ static int insert_key_button_exec (bContext *C, wmOperator *op)
                                length= 1;
                        
                        for (a=0; a<length; a++)
-                               success+= insert_keyframe(ptr.id.data, NULL, NULL, path, index+a, cfra, 0);
+                               success+= insert_keyframe(ptr.id.data, NULL, NULL, path, index+a, cfra, flag);
                        
                        MEM_freeN(path);
                }
                else if (ptr.type == &RNA_NlaStrip) {
                        /* handle special vars for NLA-strips */
                        NlaStrip *strip= (NlaStrip *)ptr.data;
-                       FCurve *fcu= list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), 0);
+                       FCurve *fcu= list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), flag);
                        
                        success+= insert_keyframe_direct(ptr, prop, fcu, cfra, 0);
                }
index 21f969467aa0488db4de4e33f6b68669a454a5a9..f81f57d526a84934570b7ed2844df5e302978363 100644 (file)
@@ -879,6 +879,7 @@ short modifykey_get_context_data (bContext *C, ListBase *dsources, KeyingSet *ks
  */
 int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
 {
+       Scene *scene= CTX_data_scene(C);
        KS_Path *ksp;
        int kflag=0, success= 0;
        char *groupname= NULL;
@@ -891,7 +892,7 @@ int modify_keyframes (bContext *C, ListBase *dsources, bAction *act, KeyingSet *
                /* suppliment with info from the context */
                if (IS_AUTOKEY_FLAG(AUTOMATKEY)) kflag |= INSERTKEY_MATRIX;
                if (IS_AUTOKEY_FLAG(INSERTNEEDED)) kflag |= INSERTKEY_NEEDED;
-               // if (IS_AUTOKEY_MODE(EDITKEYS)) flag |= INSERTKEY_REPLACE;
+               if (IS_AUTOKEY_MODE(scene, EDITKEYS)) kflag |= INSERTKEY_REPLACE;
        }
        else if (mode == MODIFYKEY_MODE_DELETE)
                kflag= 0;
index 259104f7263c83879a2922ad0a403c087b5f4ef5..0969398f1e2dfcc379efda343e0aed5fca0f6064 100644 (file)
@@ -99,7 +99,7 @@ typedef enum eKeyframeShapeDrawOpts {
 } eKeyframeShapeDrawOpts;
 
 /* draw simple diamond-shape keyframe (with OpenGL) */
-void draw_keyframe_shape (float x, float y, float xscale, float hsize, short sel, short key_type, short mode);
+void draw_keyframe_shape(float x, float y, float xscale, float hsize, short sel, short key_type, short mode);
 
 /* ******************************* Methods ****************************** */
 
index 390729eaec43c39528a655b48d61be4d85788704..b2bf05ea5ea8b7b2001d966e1c0d3a11014d0ecf 100644 (file)
@@ -147,6 +147,7 @@ void duplicate_fcurve_keys(struct FCurve *fcu);
 
 void clean_fcurve(struct FCurve *fcu, float thresh);
 void smooth_fcurve(struct FCurve *fcu);
+void sample_fcurve(struct FCurve *fcu);
 
 /* ----------- */
 
index 4bc24a0adeb5b0a35879df85ab5b49cba912704a..c492143751cbb90a76a6645d5ea3ddd861309de9 100644 (file)
@@ -65,13 +65,14 @@ struct FCurve *verify_fcurve(struct bAction *act, const char group[], const char
  *     Use this when validation of necessary animation data isn't necessary as it already
  *     exists, and there is a beztriple that can be directly copied into the array.
  */
-int insert_bezt_fcurve(struct FCurve *fcu, struct BezTriple *bezt);
+int insert_bezt_fcurve(struct FCurve *fcu, struct BezTriple *bezt, short flag);
 
 /* Main Keyframing API call: 
  *     Use this when validation of necessary animation data isn't necessary as it
  *     already exists. It will insert a keyframe using the current value being keyframed.
+ *     Returns the index at which a keyframe was added (or -1 if failed)
  */
-void insert_vert_fcurve(struct FCurve *fcu, float x, float y, short flag);
+int insert_vert_fcurve(struct FCurve *fcu, float x, float y, short flag);
 
 /* -------- */
 
index 784d820ea52868eec548bdd364bfe6af7bb19109..d7904a19bfe33b20e0ef2bf17cd59e79e953bccd 100644 (file)
@@ -152,6 +152,8 @@ void ui_but_anim_autokey(uiBut *but, Scene *scene, float cfra)
                                flag |= INSERTKEY_NEEDED;
                        if (IS_AUTOKEY_FLAG(AUTOMATKEY))
                                flag |= INSERTKEY_MATRIX;
+                       if (IS_AUTOKEY_MODE(scene, EDITKEYS))
+                               flag |= INSERTKEY_REPLACE;
                        
                        fcu->flag &= ~FCURVE_SELECTED;
                        insert_keyframe(id, action, ((fcu->grp)?(fcu->grp->name):(NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
index b087736a368505b08a8d3031c4dfa451f6f5d0c5..89633d0cdfea3cb44856b9d62e88cae042ed19c7 100644 (file)
@@ -397,7 +397,7 @@ static void insert_action_keys(bAnimContext *ac, short mode)
        /* init keyframing flag */
        if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX;
        if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED;
-       // if (IS_AUTOKEY_MODE(EDITKEYS)) flag |= INSERTKEY_REPLACE;
+       if (IS_AUTOKEY_MODE(scene, EDITKEYS)) flag |= INSERTKEY_REPLACE;
        
        /* insert keyframes */
        for (ale= anim_data.first; ale; ale= ale->next) {
@@ -679,11 +679,6 @@ void ACT_OT_clean (wmOperatorType *ot)
 
 /* ******************** Sample Keyframes Operator *********************** */
 
-/* little cache for values... */
-typedef struct tempFrameValCache {
-       float frame, val;
-} tempFrameValCache;
-
 /* Evaluates the curves between each selected keyframe on each frame, and keys the value  */
 static void sample_action_keys (bAnimContext *ac)
 {      
@@ -696,64 +691,8 @@ static void sample_action_keys (bAnimContext *ac)
        ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
        
        /* loop through filtered data and add keys between selected keyframes on every frame  */
-       for (ale= anim_data.first; ale; ale= ale->next) {
-               FCurve *fcu= (FCurve *)ale->key_data;
-               BezTriple *bezt, *start=NULL, *end=NULL;
-               tempFrameValCache *value_cache, *fp;
-               int sfra, range;
-               int i, n;
-               
-               /* find selected keyframes... once pair has been found, add keyframes  */
-               for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
-                       /* check if selected, and which end this is */
-                       if (BEZSELECTED(bezt)) {
-                               if (start) {
-                                       /* set end */
-                                       end= bezt;
-                                       
-                                       /* cache values then add keyframes using these values, as adding
-                                        * keyframes while sampling will affect the outcome...
-                                        */
-                                       range= (int)( ceil(end->vec[1][0] - start->vec[1][0]) );
-                                       sfra= (int)( floor(start->vec[1][0]) );
-                                       
-                                       if (range) {
-                                               value_cache= MEM_callocN(sizeof(tempFrameValCache)*range, "IcuFrameValCache");
-                                               
-                                               /*      sample values   */
-                                               for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
-                                                       fp->frame= (float)(sfra + n);
-                                                       fp->val= evaluate_fcurve(fcu, fp->frame);
-                                               }
-                                               
-                                               /*      add keyframes with these        */
-                                               for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
-                                                       insert_vert_fcurve(fcu, fp->frame, fp->val, 1);
-                                               }
-                                               
-                                               /* free temp cache */
-                                               MEM_freeN(value_cache);
-                                               
-                                               /* as we added keyframes, we need to compensate so that bezt is at the right place */
-                                               bezt = fcu->bezt + i + range - 1;
-                                               i += (range - 1);
-                                       }
-                                       
-                                       /* bezt was selected, so it now marks the start of a whole new chain to search */
-                                       start= bezt;
-                                       end= NULL;
-                               }
-                               else {
-                                       /* just set start keyframe */
-                                       start= bezt;
-                                       end= NULL;
-                               }
-                       }
-               }
-               
-               /* recalculate channel's handles? */
-               calchandles_fcurve(fcu);
-       }
+       for (ale= anim_data.first; ale; ale= ale->next)
+               sample_fcurve((FCurve *)ale->key_data);
        
        /* admin and redraws */
        BLI_freelistN(&anim_data);
index f18d31915f9247130e5082c5131b694033f2e72f..8674f481a1871c324a041251f75befe998d95152 100644 (file)
@@ -431,7 +431,7 @@ void action_header_buttons(const bContext *C, ARegion *ar)
                                                "Auto-snapping mode for keyframes when transforming");
                        }
                        
-                       xco += (70 + 8);
+                       xco += (90 + 8);
                }
                
                /* COPY PASTE */
index 37389b32b3a7a7c5faf832e83ed161412a39fe33..d718ef28e99a0f1b51e9411514eff33d1a700ce3 100644 (file)
@@ -430,7 +430,7 @@ static void insert_graph_keys(bAnimContext *ac, short mode)
        /* init keyframing flag */
        if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX;
        if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED;
-       // if (IS_AUTOKEY_MODE(EDITKEYS)) flag |= INSERTKEY_REPLACE;
+       if (IS_AUTOKEY_MODE(scene, EDITKEYS)) flag |= INSERTKEY_REPLACE;
        
        /* insert keyframes */
        for (ale= anim_data.first; ale; ale= ale->next) {
@@ -989,13 +989,6 @@ void GRAPH_OT_bake (wmOperatorType *ot)
  * of selected keyframes. It is useful for creating keyframes for tweaking overlap.
  */
 
-// XXX some of the common parts (with DopeSheet) should be unified in animation module...
-
-/* little cache for values... */
-typedef struct tempFrameValCache {
-       float frame, val;
-} tempFrameValCache;
-
 /* Evaluates the curves between each selected keyframe on each frame, and keys the value  */
 static void sample_graph_keys (bAnimContext *ac)
 {      
@@ -1008,64 +1001,8 @@ static void sample_graph_keys (bAnimContext *ac)
        ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
        
        /* loop through filtered data and add keys between selected keyframes on every frame  */
-       for (ale= anim_data.first; ale; ale= ale->next) {
-               FCurve *fcu= (FCurve *)ale->key_data;
-               BezTriple *bezt, *start=NULL, *end=NULL;
-               tempFrameValCache *value_cache, *fp;
-               int sfra, range;
-               int i, n;
-               
-               /* find selected keyframes... once pair has been found, add keyframes  */
-               for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
-                       /* check if selected, and which end this is */
-                       if (BEZSELECTED(bezt)) {
-                               if (start) {
-                                       /* set end */
-                                       end= bezt;
-                                       
-                                       /* cache values then add keyframes using these values, as adding
-                                        * keyframes while sampling will affect the outcome...
-                                        */
-                                       range= (int)( ceil(end->vec[1][0] - start->vec[1][0]) );
-                                       sfra= (int)( floor(start->vec[1][0]) );
-                                       
-                                       if (range) {
-                                               value_cache= MEM_callocN(sizeof(tempFrameValCache)*range, "IcuFrameValCache");
-                                               
-                                               /*      sample values   */
-                                               for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
-                                                       fp->frame= (float)(sfra + n);
-                                                       fp->val= evaluate_fcurve(fcu, fp->frame);
-                                               }
-                                               
-                                               /*      add keyframes with these        */
-                                               for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
-                                                       insert_vert_fcurve(fcu, fp->frame, fp->val, 1);
-                                               }
-                                               
-                                               /* free temp cache */
-                                               MEM_freeN(value_cache);
-                                               
-                                               /* as we added keyframes, we need to compensate so that bezt is at the right place */
-                                               bezt = fcu->bezt + i + range - 1;
-                                               i += (range - 1);
-                                       }
-                                       
-                                       /* bezt was selected, so it now marks the start of a whole new chain to search */
-                                       start= bezt;
-                                       end= NULL;
-                               }
-                               else {
-                                       /* just set start keyframe */
-                                       start= bezt;
-                                       end= NULL;
-                               }
-                       }
-               }
-               
-               /* recalculate channel's handles? */
-               calchandles_fcurve(fcu);
-       }
+       for (ale= anim_data.first; ale; ale= ale->next)
+               sample_fcurve((FCurve *)ale->key_data);
        
        /* admin and redraws */
        BLI_freelistN(&anim_data);
index e0dfd90a3d14e271ec6b175eb54a045e1a2778ac..302d9b675a02b3cd64c889097bd6575cbccc1bcd 100644 (file)
@@ -1748,7 +1748,7 @@ void flushTransParticles(TransInfo *t)
        Object *ob = OBACT;
        PTCacheEdit *edit = PE_get_current(scene, ob);
        ParticleSystem *psys = edit->psys;
-       ParticleSystemModifierData *psmd;
+       ParticleSystemModifierData *psmd = NULL;
        PTCacheEditPoint *point;
        PTCacheEditKey *key;
        TransData *td;
@@ -4348,12 +4348,14 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
                AnimData *adt= ob->adt;
                float cfra= (float)CFRA; // xxx this will do for now
                short flag = 0;
-
+               
                if (IS_AUTOKEY_FLAG(INSERTNEEDED))
                        flag |= INSERTKEY_NEEDED;
                if (IS_AUTOKEY_FLAG(AUTOMATKEY))
                        flag |= INSERTKEY_MATRIX;
-
+               if (IS_AUTOKEY_MODE(scene, EDITKEYS))
+                       flag |= INSERTKEY_REPLACE;
+                       
                if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
                        /* only key on available channels */
                        if (adt && adt->action) {
@@ -4365,7 +4367,7 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
                }
                else if (IS_AUTOKEY_FLAG(INSERTNEEDED)) {
                        short doLoc=0, doRot=0, doScale=0;
-
+                       
                        /* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */
                        if (tmode == TFM_TRANSLATION) {
                                doLoc = 1;
@@ -4377,7 +4379,7 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
                                }
                                else if (v3d->around == V3D_CURSOR)
                                        doLoc = 1;
-
+                               
                                if ((v3d->flag & V3D_ALIGN)==0)
                                        doRot = 1;
                        }
@@ -4388,11 +4390,11 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
                                }
                                else if (v3d->around == V3D_CURSOR)
                                        doLoc = 1;
-
+                               
                                if ((v3d->flag & V3D_ALIGN)==0)
                                        doScale = 1;
                        }
-
+                       
                        // TODO: the group names here are temporary...
                        // TODO: should this be made to use the builtin KeyingSets instead?
                        if (doLoc) {
@@ -4417,16 +4419,16 @@ void autokeyframe_ob_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode)
                        insert_keyframe(id, NULL, "Object Transform", "location", 0, cfra, flag);
                        insert_keyframe(id, NULL, "Object Transform", "location", 1, cfra, flag);
                        insert_keyframe(id, NULL, "Object Transform", "location", 2, cfra, flag);
-
+                       
                        insert_keyframe(id, NULL, "Object Transform", "rotation", 0, cfra, flag);
                        insert_keyframe(id, NULL, "Object Transform", "rotation", 1, cfra, flag);
                        insert_keyframe(id, NULL, "Object Transform", "rotation", 2, cfra, flag);
-
+                       
                        insert_keyframe(id, NULL, "Object Transform", "scale", 0, cfra, flag);
                        insert_keyframe(id, NULL, "Object Transform", "scale", 1, cfra, flag);
                        insert_keyframe(id, NULL, "Object Transform", "scale", 2, cfra, flag);
                }
-
+                       
                // XXX todo... find a way to send notifiers from here...
        }
 }
@@ -4450,7 +4452,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
                float cfra= (float)CFRA;
                short flag= 0;
                char buf[512];
-
+               
                /* flag is initialised from UserPref keyframing settings
                 *      - special exception for targetless IK - INSERTKEY_MATRIX keyframes should get
                 *        visual keyframes even if flag not set, as it's not that useful otherwise
@@ -4460,12 +4462,14 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
                        flag |= INSERTKEY_MATRIX;
                if (IS_AUTOKEY_FLAG(INSERTNEEDED))
                        flag |= INSERTKEY_NEEDED;
-
+               if (IS_AUTOKEY_MODE(scene, EDITKEYS))
+                       flag |= INSERTKEY_REPLACE;
+               
                for (pchan=pose->chanbase.first; pchan; pchan=pchan->next) {
                        if (pchan->bone->flag & BONE_TRANSFORM) {
                                /* clear any 'unkeyed' flag it may have */
                                pchan->bone->flag &= ~BONE_UNKEYED;
-
+                               
                                /* only insert into available channels? */
                                if (IS_AUTOKEY_FLAG(INSERTAVAIL)) {
                                        if (act) {
@@ -4476,7 +4480,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
                                /* only insert keyframe if needed? */
                                else if (IS_AUTOKEY_FLAG(INSERTNEEDED)) {
                                        short doLoc=0, doRot=0, doScale=0;
-
+                                       
                                        /* filter the conditions when this happens (assume that curarea->spacetype==SPACE_VIE3D) */
                                        if (tmode == TFM_TRANSLATION) {
                                                if (targetless_ik)
@@ -4487,18 +4491,18 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
                                        else if (tmode == TFM_ROTATION) {
                                                if (ELEM(v3d->around, V3D_CURSOR, V3D_ACTIVE))
                                                        doLoc = 1;
-
+                                                       
                                                if ((v3d->flag & V3D_ALIGN)==0)
                                                        doRot = 1;
                                        }
                                        else if (tmode == TFM_RESIZE) {
                                                if (ELEM(v3d->around, V3D_CURSOR, V3D_ACTIVE))
                                                        doLoc = 1;
-
+                                                       
                                                if ((v3d->flag & V3D_ALIGN)==0)
                                                        doScale = 1;
                                        }
-
+                                       
                                        if (doLoc) {
                                                sprintf(buf, "pose.pose_channels[\"%s\"].location", pchan->name);
                                                insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
@@ -4533,7 +4537,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
                                        insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
                                        insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
                                        insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
-
+                                       
                                        if (pchan->rotmode == PCHAN_ROT_QUAT) {
                                                sprintf(buf, "pose.pose_channels[\"%s\"].rotation", pchan->name);
                                                insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
@@ -4547,7 +4551,7 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
                                                insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
                                                insert_keyframe(id, NULL, pchan->name, buf, 2, cfra, flag);
                                        }
-
+                                       
                                        sprintf(buf, "pose.pose_channels[\"%s\"].scale", pchan->name);
                                        insert_keyframe(id, NULL, pchan->name, buf, 0, cfra, flag);
                                        insert_keyframe(id, NULL, pchan->name, buf, 1, cfra, flag);
@@ -4555,14 +4559,14 @@ void autokeyframe_pose_cb_func(Scene *scene, View3D *v3d, Object *ob, int tmode,
                                }
                        }
                }
-
+               
                // XXX todo... figure out way to get appropriate notifiers sent
-
+               
                /* do the bone paths */
-#if 0 // TRANSFORM_FIX_ME
+#if 0 // XXX TRANSFORM FIX ME
                if (arm->pathflag & ARM_PATH_ACFRA) {
-                       pose_clear_paths(ob);
-                       pose_recalculate_paths(ob);
+                       //pose_clear_paths(ob); // XXX for now, don't need to clear
+                       ED_pose_recalculate_paths(C, scene, ob);
                }
 #endif
        }