2.5 - Action Editor / Animation Stuff:
[blender-staging.git] / source / blender / editors / space_action / action_edit_keyframes.c
index 4975a2cd6de3117c879998499e8cf7ca9d766f40..df62de9bd8386abc14acd7a7de7168a594660656 100644 (file)
 /* GENERAL STUFF */
 
 // TODO:
-//     - clean
-//     - sample
 //     - delete
 //     - insert key
 //     - copy/paste
 
+/* ******************** Delete Keyframes Operator ************************* */
+
+static void delete_action_keys (bAnimContext *ac)
+{
+       ListBase anim_data = {NULL, NULL};
+       bAnimListElem *ale;
+       int filter;
+       
+       /* filter data */
+       if (ac->datatype == ANIMCONT_GPENCIL)
+               filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT);
+       else
+               filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_IPOKEYS);
+       ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
+       
+       /* loop through filtered data and delete selected keys */
+       for (ale= anim_data.first; ale; ale= ale->next) {
+               //if (ale->type == ANIMTYPE_GPLAYER)
+               //      delete_gplayer_frames((bGPDlayer *)ale->data);
+               //else
+                       delete_ipo_keys((Ipo *)ale->key_data);
+       }
+       
+       /* free filtered list */
+       BLI_freelistN(&anim_data);
+}
+
+/* ------------------- */
+
+static int actkeys_delete_exec(bContext *C, wmOperator *op)
+{
+       bAnimContext ac;
+       
+       /* get editor data */
+       if (ANIM_animdata_get_context(C, &ac) == 0)
+               return OPERATOR_CANCELLED;
+               
+       /* delete keyframes */
+       delete_action_keys(&ac);
+       
+       /* validate keyframes after editing */
+       ANIM_editkeyframes_refresh(&ac);
+       
+       /* set notifier tha things have changed */
+       ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead!
+       
+       return OPERATOR_FINISHED;
+}
+void ACT_OT_keyframes_delete (wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Delete Keyframes";
+       ot->idname= "ACT_OT_keyframes_delete";
+       
+       /* api callbacks */
+       ot->exec= actkeys_delete_exec;
+       ot->poll= ED_operator_areaactive;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
+}
+
+/* ******************** Clean Keyframes Operator ************************* */
+
+static void clean_action_keys (bAnimContext *ac, float thresh)
+{      
+       ListBase anim_data = {NULL, NULL};
+       bAnimListElem *ale;
+       int filter;
+       
+       /* filter data */
+       filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_SEL | ANIMFILTER_ONLYICU);
+       ANIM_animdata_filter(&anim_data, filter, ac->data, ac->datatype);
+       
+       /* loop through filtered data and clean curves */
+       for (ale= anim_data.first; ale; ale= ale->next)
+               clean_ipo_curve((IpoCurve *)ale->key_data, thresh);
+       
+       /* free temp data */
+       BLI_freelistN(&anim_data);
+}
+
+/* ------------------- */
+
+static int actkeys_clean_exec(bContext *C, wmOperator *op)
+{
+       bAnimContext ac;
+       float thresh;
+       
+       /* get editor data */
+       if (ANIM_animdata_get_context(C, &ac) == 0)
+               return OPERATOR_CANCELLED;
+       if (ac.datatype == ANIMCONT_GPENCIL)
+               return OPERATOR_PASS_THROUGH;
+               
+       /* get cleaning threshold */
+       thresh= RNA_float_get(op->ptr, "threshold");
+       
+       /* clean keyframes */
+       clean_action_keys(&ac, thresh);
+       
+       /* validate keyframes after editing */
+       ANIM_editkeyframes_refresh(&ac);
+       
+       /* set notifier tha things have changed */
+       ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead!
+       
+       return OPERATOR_FINISHED;
+}
+void ACT_OT_keyframes_clean (wmOperatorType *ot)
+{
+       PropertyRNA *prop;
+       
+       /* identifiers */
+       ot->name= "Clean Keyframes";
+       ot->idname= "ACT_OT_keyframes_clean";
+       
+       /* api callbacks */
+       //ot->invoke=  // XXX we need that number popup for this! 
+       ot->exec= actkeys_clean_exec;
+       ot->poll= ED_operator_areaactive;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
+       
+       /* properties */
+       prop= RNA_def_property(ot->srna, "threshold", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_default(prop, 0.001f);
+}
+
+/* ******************** 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)
+{      
+       ListBase anim_data = {NULL, NULL};
+       bAnimListElem *ale;
+       int filter;
+       
+       /* filter data */
+       filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ONLYICU);
+       ANIM_animdata_filter(&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) {
+               IpoCurve *icu= (IpoCurve *)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=icu->bezt; i < icu->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= eval_icu(icu, fp->frame);
+                                               }
+                                               
+                                               /*      add keyframes with these        */
+                                               for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
+                                                       insert_vert_icu(icu, 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 = icu->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_ipocurve(icu);
+       }
+       
+       /* admin and redraws */
+       BLI_freelistN(&anim_data);
+}
+
+/* ------------------- */
+
+static int actkeys_sample_exec(bContext *C, wmOperator *op)
+{
+       bAnimContext ac;
+       
+       /* get editor data */
+       if (ANIM_animdata_get_context(C, &ac) == 0)
+               return OPERATOR_CANCELLED;
+       if (ac.datatype == ANIMCONT_GPENCIL)
+               return OPERATOR_PASS_THROUGH;
+       
+       /* sample keyframes */
+       sample_action_keys(&ac);
+       
+       /* validate keyframes after editing */
+       ANIM_editkeyframes_refresh(&ac);
+       
+       /* set notifier tha things have changed */
+       ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead!
+       
+       return OPERATOR_FINISHED;
+}
+void ACT_OT_keyframes_sample (wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Sample Keyframes";
+       ot->idname= "ACT_OT_keyframes_sample";
+       
+       /* api callbacks */
+       ot->exec= actkeys_sample_exec;
+       ot->poll= ED_operator_areaactive;
+       
+       /* flags */
+       ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
+}
+
 /* ************************************************************************** */
 /* SETTINGS STUFF */
 
-// TODO: 
-//     - wkey stuff
-
 /* ******************** Set Extrapolation-Type Operator *********************** */
 
 /* defines for set ipo-type for selected keyframes tool */