[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12949] trunk/blender/source/blender/src/ editaction.c: == Action Editor - Copy/Paste ==

Joshua Leung aligorith at gmail.com
Wed Dec 19 23:37:39 CET 2007


Revision: 12949
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12949
Author:   aligorith
Date:     2007-12-19 23:37:38 +0100 (Wed, 19 Dec 2007)

Log Message:
-----------
== 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. 

Modified Paths:
--------------
    trunk/blender/source/blender/src/editaction.c

Modified: trunk/blender/source/blender/src/editaction.c
===================================================================
--- trunk/blender/source/blender/src/editaction.c	2007-12-19 18:17:56 UTC (rev 12948)
+++ trunk/blender/source/blender/src/editaction.c	2007-12-19 22:37:38 UTC (rev 12949)
@@ -1144,10 +1144,9 @@
 
 /* **************************************************** */
 /* 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 @@
 /* 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 @@
 	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);
 		}
-		/* allocate memory for a new curve if a valid one wasn't found */
-		if (nin_buffer) {
-			icn= MEM_callocN(sizeof(IpoCurve), "actcopybuf");
+		else if (ale->ownertype == ACTTYPE_SHAPEKEY) {
+			achan= MEM_callocN(sizeof(bActionChannel), "ActCopyPasteAchan");
+			strcpy(achan->name, "#ACP_ShapeKey");
+		}
+		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");
 		}
+		else {
+			achan->ipo= ipn= MEM_callocN(sizeof(Ipo), "ActCopyPasteIpo");
+		}
+		ipn->blocktype = ipo->blocktype;
 		
-		/* 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);
+		/* 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 @@
 	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;
+					/* recalculate channel's handles? */
+					calchandles_ipocurve(icu);
 					
-					/* 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;
+					/* done for this channel */
+					break;
 				}
-				
-				/* recalculate channel's handles? */
-				calchandles_ipocurve(icu);
-				
-				/* done for this channel */
-				break;
 			}
 		}
 	}





More information about the Bf-blender-cvs mailing list