Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2007-12-20 01:37:38 +0300
committerJoshua Leung <aligorith@gmail.com>2007-12-20 01:37:38 +0300
commit361d23224c356aa46769a0b8102752d757231df8 (patch)
tree6c63cbe5384e5c7e0cd5000c5d8ae8b1d487b27a /source/blender/src
parentb8ca87a0baefe10317fae87528f3eb2f0bf372c2 (diff)
== Action Editor - Copy/Paste ==
Now the Copy/Paste functionality stores more info about where keyframes came from. This allows users to copy full poses in the Action Editor and paste them in another action. Peach request/bugfix for William.
Diffstat (limited to 'source/blender/src')
-rw-r--r--source/blender/src/editaction.c202
1 files changed, 140 insertions, 62 deletions
diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c
index dc13e5d3019..c9e2df8d9eb 100644
--- a/source/blender/src/editaction.c
+++ b/source/blender/src/editaction.c
@@ -1144,10 +1144,9 @@ void clean_action (void)
/* **************************************************** */
/* COPY/PASTE FOR ACTIONS */
-/* - The copy/paste buffer currently stores a set of IPO curves, with no
- * repeating curve-types (i.e. no curves with the same adrcode).
- * - Only selected keyframes from the source curves are placed here.
- * - Only 'compatible' pastes are done.
+/* - The copy/paste buffer currently stores a set of Action Channels, with temporary
+ * IPO-blocks, and also temporary IpoCurves which only contain the selected keyframes.
+ * - Only pastes between compatable data is possible (i.e. same achan->name, ipo-curve type, etc.)
*/
/* globals for copy/paste data (like for other copy/paste buffers) */
@@ -1156,16 +1155,34 @@ ListBase actcopybuf = {NULL, NULL};
/* This function frees any MEM_calloc'ed copy/paste buffer data */
void free_actcopybuf ()
{
- IpoCurve *icu;
+ bActionChannel *achan, *anext;
+ bConstraintChannel *conchan, *cnext;
- while( (icu= actcopybuf.first) ) {
- BLI_remlink(&actcopybuf, icu);
- free_ipo_curve(icu);
+ for (achan= actcopybuf.first; achan; achan= next) {
+ next= achan->next;
+
+ if (achan->ipo) {
+ free_ipo(achan->ipo);
+ MEM_freeN(achan->ipo);
+ }
+
+ for (conchan=achan->constraintChannels.first; conchan; conchan=cnext) {
+ cnext= conchan->next;
+
+ if (conchan->ipo) {
+ free_ipo(conchan->ipo);
+ MEM_freeN(conchan->ipo);
+ }
+
+ BLI_freelistN(&achan->constraintChannels, conchan);
+ }
+
+ BLI_freelinkN(&actcopybuf, achan);
}
}
/* This function adds data to the copy/paste buffer, freeing existing data first
- * Only the active action channel gets its selected keyframes copied.
+ * Only the selected action channels gets their selected keyframes copied.
*/
void copy_actdata ()
{
@@ -1183,40 +1200,61 @@ void copy_actdata ()
if (data == NULL) return;
/* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_ONLYICU);
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
- /* each of these entries should be an ipo curve */
+ /* assume that each of these is an ipo-block */
for (ale= act_data.first; ale; ale= ale->next) {
- IpoCurve *icu= ale->key_data;
- IpoCurve *icn;
+ bActionChannel *achan;
+ Ipo *ipo= ale->key_data;
+ Ipo *ipn;
+ IpoCurve *icu, *icn;
BezTriple *bezt;
- short nin_buffer= 1;
int i;
- /* check if a curve like this exists already in buffer */
- for (icn= actcopybuf.first; icn; icn= icn->next) {
- if ((icn->blocktype==icu->blocktype) && (icn->adrcode==icu->adrcode)) {
- nin_buffer= 0;
- break;
- }
+ /* coerce an action-channel out of owner */
+ if (ale->ownertype == ACTTYPE_ACHAN) {
+ bActionChannel *achanO= ale->owner;
+ achan= MEM_callocN(sizeof(bActionChannel), "ActCopyPasteAchan");
+ strcpy(achan->name, achanO->name);
+ }
+ else if (ale->ownertype == ACTTYPE_SHAPEKEY) {
+ achan= MEM_callocN(sizeof(bActionChannel), "ActCopyPasteAchan");
+ strcpy(achan->name, "#ACP_ShapeKey");
}
- /* allocate memory for a new curve if a valid one wasn't found */
- if (nin_buffer) {
- icn= MEM_callocN(sizeof(IpoCurve), "actcopybuf");
+ else
+ continue;
+ BLI_addtail(&actcopybuf, achan);
+
+ /* add constraint channel if needed, then add new ipo-block */
+ if (ale->type == ACTTYPE_CONCHAN) {
+ bConstraintChannel *conchanO= ale->data;
+ bConstraintChannel *conchan;
- *icn= *icu;
- icn->totvert= 0;
- icn->bezt = NULL;
- icn->driver = NULL;
+ conchan= MEM_callocN(sizeof(bConstraintChannel), "ActCopyPasteConchan");
+ strcpy(conchan->name, conchanO->name);
+ BLI_addtail(&achan->constraintChannels, conchan);
- BLI_addtail(&actcopybuf, icn);
+ conchan->ipo= ipn= MEM_callocN(sizeof(Ipo), "ActCopyPasteIpo");
}
-
- /* find selected BezTriples to add to the buffer */
- for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
- if (BEZSELECTED(bezt))
- insert_bezt_icu(icn, bezt);
+ else {
+ achan->ipo= ipn= MEM_callocN(sizeof(Ipo), "ActCopyPasteIpo");
+ }
+ ipn->blocktype = ipo->blocktype;
+
+ /* now loop through curves, and only copy selected keyframes */
+ for (icu= ipo->curve.first; icu; icu= icu->next) {
+ /* allocate a new curve */
+ icn= MEM_callocN(sizeof(IpoCurve), "ActCopyPasteIcu");
+ icn->blocktype = icu->blocktype;
+ icn->adrcode = icu->adrcode;
+ BLI_addtail(&ipn->curve, icn);
+
+ /* find selected BezTriples to add to the buffer */
+ for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
+ if (BEZSELECTED(bezt))
+ insert_bezt_icu(icn, bezt);
+ }
}
}
@@ -1247,48 +1285,88 @@ void paste_actdata ()
if (data == NULL) return;
/* filter data */
- filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_FOREDIT | ACTFILTER_ONLYICU);
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_SEL | ACTFILTER_FOREDIT | ACTFILTER_IPOKEYS);
actdata_filter(&act_data, filter, data, datatype);
/* from selected channels */
for (ale= act_data.first; ale; ale= ale->next) {
- IpoCurve *icu= ale->key_data;
- IpoCurve *ico;
+ Ipo *ipo_src=NULL, *ipo_dst=ale->key_data;
+ bActionChannel *achan;
+ IpoCurve *ico, *icu;
BezTriple *bezt;
int i;
float offset= 0.0f;
short offsetInit= 1;
- /* find matching ipo-curve */
- for (ico= actcopybuf.first; ico; ico= ico->next) {
- if ((ico->blocktype==icu->blocktype) && (ico->adrcode==icu->adrcode)) {
- /* just start pasting, with the the first keyframe on the current frame, and so on */
- for (i=0, bezt=ico->bezt; i < ico->totvert; i++, bezt++) {
- /* initialise offset (if not already done) */
- if (offsetInit) {
- offset= CFRA - bezt->vec[1][0];
- offsetInit= 0;
+ /* find matching ipo-block */
+ for (achan= actcopybuf.first; achan; achan= achan->next) {
+ /* try to match data */
+ if (ale->ownertype == ACTTYPE_ACHAN) {
+ bActionChannel *achant= ale->owner;
+
+ /* check if we have a corresponding action channel */
+ if (strcmp(achan->name, achant->name)==0) {
+ /* check if this is a constraint channel */
+ if (ale->type == ACTTYPE_CONCHAN) {
+ bConstraintChannel *conchant= ale->data;
+ bConstraintChannel *conchan;
+
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
+ if (strcmp(conchan->name, conchant->name)==0) {
+ ipo_src= conchan->ipo;
+ break;
+ }
+ }
+ if (ipo_src) break;
+ }
+ else {
+ ipo_src= achan->ipo;
+ break;
+ }
+ }
+ }
+ else if (ale->ownertype == ACTTYPE_SHAPEKEY) {
+ /* check if this action channel is "#ACP_ShapeKey" */
+ if (strcmp(achan->name, "#ACP_ShapeKey")==0) {
+ ipo_src= achan->ipo;
+ break;
+ }
+ }
+ }
+
+ /* loop over curves, pasting keyframes */
+ for (icu= ipo_dst->curve.first; icu; icu= icu->next) {
+ for (ico= ipo_src->curve.first; ico; ico= ico->next) {
+ /* only paste if compatable blocktype + adrcode */
+ if ((ico->blocktype==icu->blocktype) && (ico->adrcode==icu->adrcode)) {
+ /* just start pasting, with the the first keyframe on the current frame, and so on */
+ for (i=0, bezt=ico->bezt; i < ico->totvert; i++, bezt++) {
+ /* initialise offset (if not already done) */
+ if (offsetInit) {
+ offset= CFRA - bezt->vec[1][0];
+ offsetInit= 0;
+ }
+
+ /* 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 */
+ insert_bezt_icu(icu, bezt);
+
+ /* un-apply offset from src beztriple after copying */
+ bezt->vec[0][0] -= offset;
+ bezt->vec[1][0] -= offset;
+ bezt->vec[2][0] -= offset;
}
- /* 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 */
- insert_bezt_icu(icu, bezt);
+ /* recalculate channel's handles? */
+ calchandles_ipocurve(icu);
- /* un-apply offset from src beztriple after copying */
- bezt->vec[0][0] -= offset;
- bezt->vec[1][0] -= offset;
- bezt->vec[2][0] -= offset;
+ /* done for this channel */
+ break;
}
-
- /* recalculate channel's handles? */
- calchandles_ipocurve(icu);
-
- /* done for this channel */
- break;
}
}
}