diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 78c87d5..aff462d 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -849,7 +849,7 @@ static float visualkey_get_value(PointerRNA *ptr, PropertyRNA *prop, int array_i * the keyframe insertion. These include the 'visual' keyframing modes, quick refresh, * and extra keyframe filtering. */ -bool insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float cfra, short flag) +BezTriple* insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float cfra, short flag) { float curval = 0.0f; @@ -912,13 +912,16 @@ bool insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *pr /* only insert keyframes where they are needed */ if (flag & INSERTKEY_NEEDED) { short insert_mode; + BezTriple* rval=0; /* check whether this curve really needs a new keyframe */ insert_mode = new_key_needed(fcu, cfra, curval); /* insert new keyframe at current frame */ - if (insert_mode) - insert_vert_fcurve(fcu, cfra, curval, flag); + if (insert_mode) { + int idx = insert_vert_fcurve(fcu, cfra, curval, flag); + rval = &fcu->bezt[idx]; + } /* delete keyframe immediately before/after newly added */ switch (insert_mode) { @@ -932,37 +935,33 @@ bool insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *pr /* only return success if keyframe added */ if (insert_mode) - return 1; + return rval; } else { /* just insert keyframe */ - insert_vert_fcurve(fcu, cfra, curval, flag); - + int idx = insert_vert_fcurve(fcu, cfra, curval, flag); + BezTriple *rval = &fcu->bezt[idx]; /* return success */ - return 1; + return rval; } /* failed */ return 0; } -/* Main Keyframing API call: - * Use this when validation of necessary animation data is necessary, since it may not exist yet. - * - * The flag argument is used for special settings that alter the behavior of - * the keyframe insertion. These include the 'visual' keyframing modes, quick refresh, - * and extra keyframe filtering. - * - * index of -1 keys all array indices +/* + * returns a heap-allocated array of BezTriple*s */ -short insert_keyframe(ReportList *reports, ID *id, bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag) +BezTriple** insert_keyframe_return_beztriples(ReportList *reports, ID *id, bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag) { PointerRNA id_ptr, ptr; PropertyRNA *prop = NULL; AnimData *adt; FCurve *fcu; int array_index_max = array_index + 1; - int ret = 0; + int ret_size; + int ret_count=0; + BezTriple** ret; // this will be NULL terminated /* validate pointer first - exit if failure */ if (id == NULL) { @@ -1008,6 +1007,9 @@ short insert_keyframe(ReportList *reports, ID *id, bAction *act, const char grou array_index_max++; } + ret_size = array_index_max - array_index; + ret = malloc((ret_size+1) * sizeof(*ret)); + /* will only loop once unless the array index was -1 */ for (; array_index < array_index_max; array_index++) { /* make sure the F-Curve exists @@ -1028,14 +1030,47 @@ short insert_keyframe(ReportList *reports, ID *id, bAction *act, const char grou } } - /* insert keyframe */ - ret += insert_keyframe_direct(reports, ptr, prop, fcu, cfra, flag); + { /* insert keyframe */ + BezTriple* keyFrame = insert_keyframe_direct(reports, ptr, prop, fcu, cfra, flag); + if ( 0 != keyFrame) { + if (ret_count>=ret_size) { + fprintf(stderr, "Holy duck crotch, you made it too small.\n"); // we should probably put a GOOD error message in here. + } else { + ret[ret_count++] = keyFrame; + } } } + } + } + + /* we saved room for the 0 at the end */ + ret[ret_count] = (void*)0; return ret; } +/* Main Keyframing API call: + * Use this when validation of necessary animation data is necessary, since it may not exist yet. + * + * The flag argument is used for special settings that alter the behavior of + * the keyframe insertion. These include the 'visual' keyframing modes, quick refresh, + * and extra keyframe filtering. + * + * index of -1 keys all array indices + */ +short insert_keyframe(ReportList *reports, ID *id, bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag) +{ + BezTriple** keyFrames = insert_keyframe_return_beztriples(reports, id, act, group, rna_path, array_index, cfra, flag); + int rval=0; + if (keyFrames!=0) { + while ( keyFrames[rval]!=0){ + rval++; + } + } + free(keyFrames); + return rval; +} + /* ************************************************** */ /* KEYFRAME DELETION */ @@ -1705,7 +1740,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op) NlaStrip *strip = (NlaStrip *)ptr.data; FCurve *fcu = list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), flag); - success += insert_keyframe_direct(op->reports, ptr, prop, fcu, cfra, 0); + success += 0 != insert_keyframe_direct(op->reports, ptr, prop, fcu, cfra, 0); } else { BKE_report(op->reports, RPT_WARNING, diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h index 5c7b3c5..278ac65 100644 --- a/source/blender/editors/include/ED_keyframing.h +++ b/source/blender/editors/include/ED_keyframing.h @@ -108,7 +108,7 @@ int insert_vert_fcurve(struct FCurve *fcu, float x, float y, short flag); * Use this to insert a keyframe using the current value being keyframed, in the * nominated F-Curve (no creation of animation data performed). Returns success. */ -bool insert_keyframe_direct(struct ReportList *reports, struct PointerRNA ptr, struct PropertyRNA *prop, struct FCurve *fcu, float cfra, short flag); +struct BezTriple* insert_keyframe_direct(struct ReportList *reports, struct PointerRNA ptr, struct PropertyRNA *prop, struct FCurve *fcu, float cfra, short flag); /* -------- */ @@ -118,6 +118,8 @@ bool insert_keyframe_direct(struct ReportList *reports, struct PointerRNA ptr, s */ short insert_keyframe(struct ReportList *reports, struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag); +struct BezTriple** insert_keyframe_return_beztriples(struct ReportList *reports, struct ID *id, struct bAction *act, const char group[], const char rna_path[], int array_index, float cfra, short flag); + /* Main Keyframing API call: * Use this to delete keyframe on current frame for relevant channel. Will perform checks just in case. */ diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c index f2881bf..6b5d970 100644 --- a/source/blender/makesrna/intern/rna_animation.c +++ b/source/blender/makesrna/intern/rna_animation.c @@ -58,6 +58,8 @@ EnumPropertyItem keyingset_path_grouping_items[] = { EnumPropertyItem keying_flag_items[] = { {INSERTKEY_NEEDED, "INSERTKEY_NEEDED", 0, "Only Needed", "Only insert keyframes where they're needed in the relevant F-Curves"}, + {INSERTKEY_REPLACE, "INSERTKEY_REPLACE", 0, "??", + "Only insert keyframes something something"}, {INSERTKEY_MATRIX, "INSERTKEY_VISUAL", 0, "Visual Keying", "Insert keyframes based on 'visual transforms'"}, {INSERTKEY_XYZ2RGB, "INSERTKEY_XYZ_TO_RGB", 0, "XYZ=RGB Colors", diff --git a/source/blender/python/intern/bpy_rna_anim.c b/source/blender/python/intern/bpy_rna_anim.c index ed51ba5..ab0e374 100644 --- a/source/blender/python/intern/bpy_rna_anim.c +++ b/source/blender/python/intern/bpy_rna_anim.c @@ -220,18 +220,48 @@ PyObject *pyrna_struct_keyframe_insert(BPy_StructRNA *self, PyObject *args, PyOb return NULL; } else { - short result; + BezTriple** result; ReportList reports; BKE_reports_init(&reports, RPT_STORE); - result = insert_keyframe(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, options); + result = insert_keyframe_return_beztriples(&reports, (ID *)self->ptr.id.data, NULL, group_name, path_full, index, cfra, options); MEM_freeN((void *)path_full); - if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) + if (BPy_reports_to_error(&reports, PyExc_RuntimeError, true) == -1) { + if (result!=0) + free(result); return NULL; + } + + { + int len=0; + PyObject *list; + int i; + + while (0 != result[len]) + len++; + + list = PyList_New(len); + for (i=0; i L<%f,%f> R<%f,%f> i=%d\n", + result[i]->vec[1][0], result[i]->vec[1][1], + result[i]->vec[0][0], result[i]->vec[0][1], + result[i]->vec[2][0], result[i]->vec[2][1], + result[i]->ipo + ); + RNA_pointer_create(0, &RNA_Keyframe, result[i], &newptr); + bacon = pyrna_struct_CreatePyObject(&newptr); + PyList_SET_ITEM(list, i, bacon); + } + + free(result); + + return list; + } - return PyBool_FromLong(result); } }