diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index 60242d3e837..fbacd22b360 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -252,20 +252,22 @@ AnimData *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale) /* ------------------- */ +typedef struct NlaMappingApplyBackup { + struct NlaMappingBackup *next, *prev; + BezTriple bezt; +} NlaMappingApplyBackup; + /* helper function for ANIM_nla_mapping_apply_fcurve() -> "restore", i.e. mapping points back to action-time */ static short bezt_nlamapping_restore(BeztEditData *bed, BezTriple *bezt) { - /* AnimData block providing scaling is stored in 'data', only_keys option is stored in i1 */ - AnimData *adt= (AnimData *)bed->data; - short only_keys= (short)bed->i1; - - /* adjust BezTriple handles only if allowed to */ - if (only_keys == 0) { - bezt->vec[0][0]= BKE_nla_tweakedit_remap(adt, bezt->vec[0][0], NLATIME_CONVERT_UNMAP); - bezt->vec[2][0]= BKE_nla_tweakedit_remap(adt, bezt->vec[2][0], NLATIME_CONVERT_UNMAP); - } - - bezt->vec[1][0]= BKE_nla_tweakedit_remap(adt, bezt->vec[1][0], NLATIME_CONVERT_UNMAP); + ListBase *lb= (ListBase*)bed->data2; + NlaMappingApplyBackup *backup= lb->first; + + /* restore beztriple from backup list. this used to use NLATIME_CONVERT_UNMAP, + but this was not the inverse of NLATIME_CONVERT_MAP and it's not clear how + that is even possible due to repeats - brecht. */ + *bezt= backup->bezt; + BLI_freelinkN(lb, backup); return 0; } @@ -274,8 +276,15 @@ static short bezt_nlamapping_restore(BeztEditData *bed, BezTriple *bezt) static short bezt_nlamapping_apply(BeztEditData *bed, BezTriple *bezt) { /* AnimData block providing scaling is stored in 'data', only_keys option is stored in i1 */ - AnimData *adt= (AnimData *)bed->data; + AnimData *adt= (AnimData*)bed->data; + ListBase *lb= (ListBase*)bed->data2; + NlaMappingApplyBackup *backup; short only_keys= (short)bed->i1; + + /* backup for restore later */ + backup= MEM_callocN(sizeof(NlaMappingApplyBackup), "NlaMappingApplyBackup"); + backup->bezt= *bezt; + BLI_addtail(lb, backup); /* adjust BezTriple handles only if allowed to */ if (only_keys == 0) { @@ -289,12 +298,11 @@ static short bezt_nlamapping_apply(BeztEditData *bed, BezTriple *bezt) } - /* Apply/Unapply NLA mapping to all keyframes in the nominated F-Curve * - restore = whether to map points back to non-mapped time * - only_keys = whether to only adjust the location of the center point of beztriples */ -void ANIM_nla_mapping_apply_fcurve (AnimData *adt, FCurve *fcu, short restore, short only_keys) +void ANIM_nla_mapping_apply_fcurve (AnimData *adt, FCurve *fcu, short restore, short only_keys, ListBase *backup) { BeztEditData bed; BeztEditFunc map_cb; @@ -305,7 +313,11 @@ void ANIM_nla_mapping_apply_fcurve (AnimData *adt, FCurve *fcu, short restore, s */ memset(&bed, 0, sizeof(BeztEditData)); bed.data= (void *)adt; + bed.data2= (void *)backup; bed.i1= (int)only_keys; + + if(!restore) + backup->first= backup->last= NULL; /* get editing callback */ if (restore) diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 42fe9160946..63633468767 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -850,12 +850,13 @@ void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys, DLRBT_Tree { DLRBT_Tree *beztTree = NULL; BezTriple *bezt; + ListBase nlabackup; int v; if (fcu && fcu->totvert && fcu->bezt) { /* apply NLA-mapping (if applicable) */ if (adt) - ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 1); + ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 1, &nlabackup); /* if getting long keyframes too, grab the BezTriples in a BST for * accelerated searching... @@ -891,7 +892,8 @@ void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys, DLRBT_Tree } /* unapply NLA-mapping if applicable */ - ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 1); + if (adt) + ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 1, &nlabackup); } } diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index 531751a609e..6d81131492a 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -453,7 +453,7 @@ void getcolor_fcurve_rainbow(int cur, int tot, float *out); struct AnimData *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale); /* Apply/Unapply NLA mapping to all keyframes in the nominated F-Curve */ -void ANIM_nla_mapping_apply_fcurve(struct AnimData *adt, struct FCurve *fcu, short restore, short only_keys); +void ANIM_nla_mapping_apply_fcurve(struct AnimData *adt, struct FCurve *fcu, short restore, short only_keys, ListBase *backup); /* ..... */ diff --git a/source/blender/editors/include/ED_keyframes_edit.h b/source/blender/editors/include/ED_keyframes_edit.h index 9e29d747d4a..d567398209f 100644 --- a/source/blender/editors/include/ED_keyframes_edit.h +++ b/source/blender/editors/include/ED_keyframes_edit.h @@ -94,6 +94,7 @@ typedef struct BeztEditData { ListBase list; /* temp list for storing custom list of data to check */ struct Scene *scene; /* pointer to current scene - many tools need access to cfra/etc. */ void *data; /* pointer to custom data - usually 'Object' but also 'rectf', but could be other types too */ + void *data2; /* pointer to more custom data */ float f1, f2; /* storage of times/values as 'decimals' */ int i1, i2; /* storage of times/values/flags as 'whole' numbers */ } BeztEditData; diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 687e7c53644..b35f9594397 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -1133,11 +1133,12 @@ static int actkeys_framejump_exec(bContext *C, wmOperator *op) for (ale= anim_data.first; ale; ale= ale->next) { AnimData *adt= ANIM_nla_mapping_get(&ac, ale); - if (adt) { - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); + ListBase nlabackup; + + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1, &nlabackup); ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, bezt_calc_average, NULL); - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1, &nlabackup); } else ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, bezt_calc_average, NULL); @@ -1215,9 +1216,11 @@ static void snap_action_keys(bAnimContext *ac, short mode) AnimData *adt= ANIM_nla_mapping_get(ac, ale); if (adt) { - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); + ListBase nlabackup; + + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1, &nlabackup); ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_fcurve); - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1, &nlabackup); } //else if (ale->type == ACTTYPE_GPLAYER) // snap_gplayer_frames(ale->data, mode); @@ -1332,9 +1335,11 @@ static void mirror_action_keys(bAnimContext *ac, short mode) AnimData *adt= ANIM_nla_mapping_get(ac, ale); if (adt) { - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); + ListBase nlabackup; + + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1, &nlabackup); ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_fcurve); - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1, &nlabackup); } //else if (ale->type == ACTTYPE_GPLAYER) // snap_gplayer_frames(ale->data, mode); diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index 8eeed6da100..9155f57c7a0 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -417,9 +417,11 @@ static void markers_selectkeys_between (bAnimContext *ac) AnimData *adt= ANIM_nla_mapping_get(ac, ale); if (adt) { - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); + ListBase nlabackup; + + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1, &nlabackup); ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1, &nlabackup); } else { ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); @@ -663,9 +665,11 @@ static void actkeys_mselect_leftright (bAnimContext *ac, short leftright, short AnimData *adt= ANIM_nla_mapping_get(ac, ale); if (adt) { - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); + ListBase nlabackup; + + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1, &nlabackup); ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1, &nlabackup); } //else if (ale->type == ANIMTYPE_GPLAYER) // borderselect_gplayer_frames(ale->data, min, max, SELECT_ADD); diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index 9681d20c13b..4735950c9d1 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -819,10 +819,11 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri FCurve *fcu= (FCurve *)ale->key_data; FModifier *fcm= find_active_fmodifier(&fcu->modifiers); AnimData *adt= ANIM_nla_mapping_get(ac, ale); + ListBase nlabackup; /* map keyframes for drawing if scaled F-Curve */ if (adt) - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0); + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0, &nlabackup); /* draw curve: * - curve line may be result of one or more destructive modifiers or just the raw data, @@ -908,7 +909,7 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri /* undo mapping of keyframes for drawing if scaled F-Curve */ if (adt) - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0); + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0, &nlabackup); } /* free list of curves */ diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 2adf783b338..1bae3686fe2 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1557,9 +1557,11 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *op) AnimData *adt= ANIM_nla_mapping_get(&ac, ale); if (adt) { - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); + ListBase nlabackup; + + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1, &nlabackup); ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, bezt_calc_average, NULL); - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1, &nlabackup); } else ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, bezt_calc_average, NULL); @@ -1645,9 +1647,11 @@ static void snap_graph_keys(bAnimContext *ac, short mode) AnimData *adt= ANIM_nla_mapping_get(ac, ale); if (adt) { - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); + ListBase nlabackup; + + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1, &nlabackup); ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_fcurve); - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1, &nlabackup); } else ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_fcurve); @@ -1762,9 +1766,11 @@ static void mirror_graph_keys(bAnimContext *ac, short mode) AnimData *adt= ANIM_nla_mapping_get(ac, ale); if (adt) { - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); + ListBase nlabackup; + + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1, &nlabackup); ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_fcurve); - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1, &nlabackup); } else ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_fcurve); diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index 8d2e2921b7f..b732d17e34f 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -394,9 +394,11 @@ static void markers_selectkeys_between (bAnimContext *ac) AnimData *adt= ANIM_nla_mapping_get(ac, ale); if (adt) { - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); + ListBase nlabackup; + + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1, &nlabackup); ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1, &nlabackup); } else { ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); @@ -589,10 +591,11 @@ static short findnearest_fcurve_vert (bAnimContext *ac, int mval[2], FCurve **fc /* try to progressively get closer to the right point... */ if (fcu->bezt) { BezTriple *bezt1=fcu->bezt, *prevbezt=NULL; + ListBase nlabackup; /* apply NLA mapping to all the keyframes */ if (adt) - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1, &nlabackup); for (i=0; i < fcu->totvert; i++, prevbezt=bezt1, bezt1++) { /* convert beztriple points to screen-space */ @@ -650,7 +653,7 @@ static short findnearest_fcurve_vert (bAnimContext *ac, int mval[2], FCurve **fc /* un-apply NLA mapping from all the keyframes */ if (adt) - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1, &nlabackup); } } @@ -797,9 +800,11 @@ static void graphkeys_mselect_leftright (bAnimContext *ac, short leftright, shor AnimData *adt= ANIM_nla_mapping_get(ac, ale); if (adt) { - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); + ListBase nlabackup; + + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1, &nlabackup); ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1, &nlabackup); } else ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 3d677d0789d..2769112e5d5 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -3014,9 +3014,11 @@ static void posttrans_action_clean (bAnimContext *ac, bAction *act) AnimData *adt= ANIM_nla_mapping_get(ac, ale); if (adt) { - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1); + ListBase nlabackup; + + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1, &nlabackup); posttrans_fcurve_clean(ale->key_data); - ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1); + ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1, &nlabackup); } else posttrans_fcurve_clean(ale->key_data); @@ -4230,7 +4232,6 @@ static void ObjectToTransData(bContext *C, TransInfo *t, TransData *td, Object * { Scene *scene = CTX_data_scene(C); Object *track; - ListBase fakecons = {NULL, NULL}; float obmtx[3][3]; short constinv; short skip_invert = 0; @@ -4784,9 +4785,11 @@ void special_aftertrans_update(bContext *C, TransInfo *t) ((cancelled == 0) || (duplicate)) ) { if (adt) { - ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 1); + ListBase nlabackup; + + ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 1, &nlabackup); posttrans_fcurve_clean(fcu); - ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 1); + ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 1, &nlabackup); } else posttrans_fcurve_clean(fcu); @@ -4865,9 +4868,11 @@ void special_aftertrans_update(bContext *C, TransInfo *t) ((cancelled == 0) || (duplicate)) ) { if (adt) { - ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 1); + ListBase nlabackup; + + ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 1, &nlabackup); posttrans_fcurve_clean(fcu); - ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 1); + ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 1, &nlabackup); } else posttrans_fcurve_clean(fcu); diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index 20d1a898303..426cb1f0772 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -85,6 +85,12 @@ static char *rna_NlaStrip_path(PointerRNA *ptr) return ""; } +static void rna_NlaStrip_transform_update(Main *bmain, PointerRNA *ptr) +{ + NlaStrip *strip= (NlaStrip*)ptr->data; + + BKE_nlameta_flush_transforms(strip); +} static void rna_NlaStrip_start_frame_set(PointerRNA *ptr, float value) { @@ -326,11 +332,13 @@ static void rna_def_nlastrip(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "start"); RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_start_frame_set", NULL); RNA_def_property_ui_text(prop, "Start Frame", ""); + RNA_def_property_update(prop, 0, "rna_NlaStrip_transform_update"); prop= RNA_def_property(srna, "end_frame", PROP_FLOAT, PROP_TIME); RNA_def_property_float_sdna(prop, NULL, "end"); RNA_def_property_float_funcs(prop, NULL, "rna_NlaStrip_end_frame_set", NULL); RNA_def_property_ui_text(prop, "End Frame", ""); + RNA_def_property_update(prop, 0, "rna_NlaStrip_transform_update"); /* Blending */ prop= RNA_def_property(srna, "blend_in", PROP_FLOAT, PROP_NONE);