[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [33569] trunk/blender/source/blender/ editors: Problem with FCurve pasting reported by Rob Garlington.
Campbell Barton
ideasman42 at gmail.com
Thu Dec 9 12:49:38 CET 2010
Revision: 33569
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=33569
Author: campbellbarton
Date: 2010-12-09 12:49:38 +0100 (Thu, 09 Dec 2010)
Log Message:
-----------
Problem with FCurve pasting reported by Rob Garlington.
- Pasting from 1 fcurve to any other fcurve now works (skip index and rna path checking).
- Pasting multiple fcurves between bones now works.
- If path checking fails, pasting matches indices so Scale XYZ can be pasted into Location XYZ for eg.
Modified Paths:
--------------
trunk/blender/source/blender/editors/animation/keyframes_general.c
trunk/blender/source/blender/editors/space_action/action_edit.c
trunk/blender/source/blender/editors/space_graph/graph_edit.c
Modified: trunk/blender/source/blender/editors/animation/keyframes_general.c
===================================================================
--- trunk/blender/source/blender/editors/animation/keyframes_general.c 2010-12-09 07:05:09 UTC (rev 33568)
+++ trunk/blender/source/blender/editors/animation/keyframes_general.c 2010-12-09 11:49:38 UTC (rev 33569)
@@ -42,7 +42,12 @@
#include "BKE_fcurve.h"
#include "BKE_utildefines.h"
+#include "BKE_report.h"
+#include "BKE_library.h"
+#include "BKE_global.h"
+#include "RNA_access.h"
+
#include "ED_anim_api.h"
#include "ED_keyframing.h"
#include "ED_keyframes_edit.h"
@@ -453,6 +458,8 @@
int totvert; /* number of keyframes stored for this channel */
BezTriple *bezt; /* keyframes in buffer */
+
+ short id_type; /* Result of GS(id->name)*/
} tAnimCopybufItem;
@@ -510,6 +517,7 @@
/* init copybuf item info */
aci= MEM_callocN(sizeof(tAnimCopybufItem), "AnimCopybufItem");
aci->id= ale->id;
+ aci->id_type= GS(ale->id->name);
aci->grp= fcu->grp;
aci->rna_path= MEM_dupallocN(fcu->rna_path);
aci->array_index= fcu->array_index;
@@ -550,74 +558,183 @@
return 0;
}
+static tAnimCopybufItem *pastebuf_match_path_full(FCurve *fcu, const short from_single, const short to_simple) {
+ tAnimCopybufItem *aci;
+
+ for (aci= animcopybuf.first; aci; aci= aci->next) {
+ /* check that paths exist */
+ if (to_simple || (aci->rna_path && fcu->rna_path)) {
+ if (to_simple || (strcmp(aci->rna_path, fcu->rna_path) == 0)) {
+ if ((from_single) || (aci->array_index == fcu->array_index)) {
+ break;
+ }
+ }
+ }
+ }
+
+ return aci;
+}
+
+static tAnimCopybufItem *pastebuf_match_path_property(FCurve *fcu, const short from_single, const short UNUSED(to_simple))
+{
+ tAnimCopybufItem *aci;
+
+ for (aci= animcopybuf.first; aci; aci= aci->next) {
+ /* check that paths exist */
+ if (aci->rna_path && fcu->rna_path) {
+
+ /* find the property of the fcurve and compare against the end of the tAnimCopybufItem
+ * more involves since it needs to to path lookups.
+ * This is not 100% reliable since the user could be editing the curves on a path that wont
+ * resolve, or a bone could be renamed after copying for eg. but in normal copy & paste
+ * this should work out ok. */
+ if(BLI_findindex(which_libbase(G.main, aci->id_type), aci->id) == -1) {
+ /* pedantic but the ID could have been removed, and beats crashing! */
+ printf("paste_animedit_keys: error ID has been removed!\n");
+ }
+ else {
+ PointerRNA id_ptr, rptr;
+ PropertyRNA *prop;
+
+ RNA_id_pointer_create(aci->id, &id_ptr);
+ RNA_path_resolve(&id_ptr, aci->rna_path, &rptr, &prop);
+
+ if(prop) {
+ const char *identifier= RNA_property_identifier(prop);
+ int len_id = strlen(identifier);
+ int len_path = strlen(fcu->rna_path);
+ if(len_id <= len_path) {
+ /* note, paths which end with "] will fail with this test - Animated ID Props */
+ if(strcmp(identifier, fcu->rna_path + (len_path-len_id))==0) {
+ if ((from_single) || (aci->array_index == fcu->array_index)) {
+ break;
+ }
+ }
+ }
+ }
+ else {
+ printf("paste_animedit_keys: failed to resolve path id:%s, '%s'!\n", aci->id->name, aci->rna_path);
+ }
+ }
+ }
+ }
+
+ return aci;
+}
+
+static tAnimCopybufItem *pastebuf_match_index_only(FCurve *fcu, const short from_single, const short UNUSED(to_simple))
+{
+ tAnimCopybufItem *aci;
+
+ for (aci= animcopybuf.first; aci; aci= aci->next) {
+ /* check that paths exist */
+ if ((from_single) || (aci->array_index == fcu->array_index)) {
+ break;
+ }
+ }
+
+ return aci;
+}
+
+static void paste_animedit_keys_fcurve(FCurve *fcu, tAnimCopybufItem *aci, float offset)
+{
+ BezTriple *bezt;
+ int i;
+
+ /* just start pasting, with the the first keyframe on the current frame, and so on */
+ for (i=0, bezt=aci->bezt; i < aci->totvert; i++, bezt++) {
+ /* temporarily apply offset to src beztriple while copying */
+ bezt->vec[0][0] += offset;
+ bezt->vec[1][0] += offset;
+ bezt->vec[2][0] += offset;
+
+ /* 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;
+ bezt->vec[1][0] -= offset;
+ bezt->vec[2][0] -= offset;
+ }
+
+ /* recalculate F-Curve's handles? */
+ calchandles_fcurve(fcu);
+}
+
/* This function pastes data from the keyframes copy/paste buffer */
short paste_animedit_keys (bAnimContext *ac, ListBase *anim_data)
{
bAnimListElem *ale;
const Scene *scene= (ac->scene);
const float offset = (float)(CFRA - animcopy_firstframe);
- short no_name= 0;
+ const short from_single= (animcopybuf.first == animcopybuf.last);
+ const short to_simple= (anim_data->first == anim_data->last);
+ int pass;
/* check if buffer is empty */
if (ELEM(NULL, animcopybuf.first, animcopybuf.last)) {
- //error("No data in buffer to paste");
+ BKE_report(ac->reports, RPT_WARNING, "No data in buffer to paste");
return -1;
}
- /* check if single channel in buffer (disregard names if so) */
- if (animcopybuf.first == animcopybuf.last)
- no_name= 1;
-
- /* from selected channels */
- for (ale= anim_data->first; ale; ale= ale->next) {
- FCurve *fcu = (FCurve *)ale->data; /* destination F-Curve */
- tAnimCopybufItem *aci= NULL;
- BezTriple *bezt;
- int i;
-
- /* find buffer item to paste from
- * - if names don't matter (i.e. only 1 channel in buffer), don't check id/group
- * - if names do matter, only check if id-type is ok for now (group check is not that important)
- * - most importantly, rna-paths should match (array indices are unimportant for now)
- */
- // TODO: the matching algorithm here is pathetic!
- for (aci= animcopybuf.first; aci; aci= aci->next) {
- /* check that paths exist */
- if (aci->rna_path && fcu->rna_path) {
- // FIXME: this breaks for bone names!
- if (strcmp(aci->rna_path, fcu->rna_path) == 0) {
- /* should be a match unless there's more than one of these */
- if ((no_name) || (aci->array_index == fcu->array_index))
- break;
- }
- }
- }
-
-
- /* copy the relevant data from the matching buffer curve */
- if (aci) {
- /* just start pasting, with the the first keyframe on the current frame, and so on */
- for (i=0, bezt=aci->bezt; i < aci->totvert; i++, bezt++) {
- /* temporarily apply offset to src beztriple while copying */
- bezt->vec[0][0] += offset;
- bezt->vec[1][0] += offset;
- bezt->vec[2][0] += offset;
+
+ if(from_single && to_simple) {
+ /* 1:1 match, no tricky checking, just paste */
+ FCurve *fcu;
+ tAnimCopybufItem *aci;
+
+ ale= anim_data->first;
+ fcu= (FCurve *)ale->data; /* destination F-Curve */
+ aci= animcopybuf.first;
+
+ paste_animedit_keys_fcurve(fcu, aci, offset);
+ }
+ else {
+ /* from selected channels */
+ for(pass= 0; pass < 3; pass++) {
+ int totmatch= 0;
+ for (ale= anim_data->first; ale; ale= ale->next) {
- /* insert the keyframe
- * NOTE: no special flags here for now
+ /* find buffer item to paste from
+ * - if names don't matter (i.e. only 1 channel in buffer), don't check id/group
+ * - if names do matter, only check if id-type is ok for now (group check is not that important)
+ * - most importantly, rna-paths should match (array indices are unimportant for now)
*/
- insert_bezt_fcurve(fcu, bezt, 0);
+ FCurve *fcu = (FCurve *)ale->data; /* destination F-Curve */
+ tAnimCopybufItem *aci= NULL;
- /* un-apply offset from src beztriple after copying */
- bezt->vec[0][0] -= offset;
- bezt->vec[1][0] -= offset;
- bezt->vec[2][0] -= offset;
+ switch(pass) {
+ case 0:
+ /* most strict, must be exact path match data_path & index */
+ aci= pastebuf_match_path_full(fcu, from_single, to_simple);
+ break;
+
+ case 1:
+ /* less strict, just compare property names */
+ aci= pastebuf_match_path_property(fcu, from_single, to_simple);
+ break;
+
+ case 2:
+ /* Comparing properties gave no results, so just do index comparisons */
+ aci= pastebuf_match_index_only(fcu, from_single, to_simple);
+ break;
+ }
+
+ /* copy the relevant data from the matching buffer curve */
+ if (aci) {
+ totmatch++;
+ paste_animedit_keys_fcurve(fcu, aci, offset);
+ }
}
- /* recalculate F-Curve's handles? */
- calchandles_fcurve(fcu);
+ /* dont continue if some fcurves were pasted */
+ if(totmatch) {
+ break;
+ }
}
}
-
+
return 0;
}
Modified: trunk/blender/source/blender/editors/space_action/action_edit.c
===================================================================
--- trunk/blender/source/blender/editors/space_action/action_edit.c 2010-12-09 07:05:09 UTC (rev 33568)
+++ trunk/blender/source/blender/editors/space_action/action_edit.c 2010-12-09 11:49:38 UTC (rev 33569)
@@ -358,6 +358,10 @@
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
+ if(ac.reports==NULL) {
+ ac.reports= op->reports;
+ }
+
/* paste keyframes */
if (ac.datatype == ANIMCONT_GPENCIL) {
// FIXME...
Modified: trunk/blender/source/blender/editors/space_graph/graph_edit.c
===================================================================
--- trunk/blender/source/blender/editors/space_graph/graph_edit.c 2010-12-09 07:05:09 UTC (rev 33568)
+++ trunk/blender/source/blender/editors/space_graph/graph_edit.c 2010-12-09 11:49:38 UTC (rev 33569)
@@ -681,9 +681,12 @@
if (ANIM_animdata_get_context(C, &ac) == 0)
return OPERATOR_CANCELLED;
+ if(ac.reports==NULL) {
+ ac.reports= op->reports;
+ }
+
/* paste keyframes */
if (paste_graph_keys(&ac)) {
- BKE_report(op->reports, RPT_ERROR, "No keyframes to paste");
return OPERATOR_CANCELLED;
}
More information about the Bf-blender-cvs
mailing list