[Bf-animsys] [PATCH] fix non-bezier key translation

Jess Balint jbalint at gmail.com
Sat May 30 08:27:15 CEST 2009


On Fri, May 29, 2009 at 10:36:42PM +1200, Joshua Leung wrote:
> Do you have any good test file for this handy?

No, how do I create one? Is there some automated testing that I haven't
stumbled upon?

> Just reading through the patch:
> IMO, you shouldn't need to be checking the next BezTriple, since each
> BezTriple defines the interpolation for the segment going from it's central
> point (bezt->vec[1] = 'v1'), its 'second' (right) handle (bezt->vec[2] =
> 'v2'), to the 'first' (left) handle of the next BezTriple (next->vec[0] =
> 'v3'), and the central point of the next BezTriple (next->vec[1] = 'v4')

Yes, you are right. That nextbezt code I had in there was really doing
nothing anyway. A little more testing revealed some issues. Basically
what I've done is make the translate take all three points into account,
even if it's not a bezier segment. There are a few reasons for this:
- would not be possible to edit the first handle of a non-bezier segment
- moving bezier segments "through" a non-bezier segment would cause the
  handles to be translated incorrectly (due to the swapping in
  bezt_map_to_data() )
- as a bonus, the handle positions don't get lost if you convert back
  and forth between bezier and non-bezier

Patch attached, let me know what you think. I've also taken the liberty
to correct the function name that was spelled incorrectly.

One question that arose - when do the bezier handles need to be
swapped? There's some code in sort_time_beztmaps() to check if it needs
to be done, but aren't the handle values clamped to the center point
before this?

Thanks.
Jess

-------------- next part --------------
Index: source/blender/editors/transform/transform_conversions.c
===================================================================
--- source/blender/editors/transform/transform_conversions.c	(revision 20473)
+++ source/blender/editors/transform/transform_conversions.c	(working copy)
@@ -1338,7 +1338,7 @@
 }
 
 /* Utility function for getting the handle data from bezier's */
-TransDataCurveHandleFlags *initTransDataCurveHandes(TransData *td, struct BezTriple *bezt) {
+TransDataCurveHandleFlags *initTransDataCurveHandles(TransData *td, struct BezTriple *bezt) {
 	TransDataCurveHandleFlags *hdata;
 	td->flag |= TD_BEZTRIPLE;
 	hdata = td->hdata = MEM_mallocN(sizeof(TransDataCurveHandleFlags), "CuHandle Data");
@@ -1428,7 +1428,7 @@
 						td->tdi = NULL;
 						td->val = NULL;
 						
-						hdata = initTransDataCurveHandes(td, bezt);
+						hdata = initTransDataCurveHandles(td, bezt);
 
 						Mat3CpyMat3(td->smtx, smtx);
 						Mat3CpyMat3(td->mtx, mtx);
@@ -1464,7 +1464,7 @@
 						if ((bezt->f1&SELECT)==0 && (bezt->f3&SELECT)==0)
 						/* If the middle is selected but the sides arnt, this is needed */
 						if (hdata==NULL) { /* if the handle was not saved by the previous handle */
-							hdata = initTransDataCurveHandes(td, bezt);
+							hdata = initTransDataCurveHandles(td, bezt);
 						}
 						
 						td++;
@@ -1490,7 +1490,7 @@
 						td->val = NULL;
 
 						if (hdata==NULL) { /* if the handle was not saved by the previous handle */
-							hdata = initTransDataCurveHandes(td, bezt);
+							hdata = initTransDataCurveHandles(td, bezt);
 						}
 						
 						Mat3CpyMat3(td->smtx, smtx);
@@ -1509,7 +1509,7 @@
 			if (propmode && head != tail)
 				calc_distanceCurveVerts(head, tail-1);
 			
-			/* TODO - in the case of tilt and radius we can also avoid allocating the initTransDataCurveHandes
+			/* TODO - in the case of tilt and radius we can also avoid allocating the initTransDataCurveHandles
 			 * but for now just dont change handle types */
 			if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT) == 0)
 				testhandlesNurb(nu); /* sets the handles based on their selection, do this after the data is copied to the TransData */
@@ -3159,7 +3159,7 @@
 		
 		/* only include BezTriples whose 'keyframe' occurs on the same side of the current frame as mouse */
 		if (fcu->bezt) {
-			for (i=0, bezt=fcu->bezt; i < fcu->totvert; i++, bezt++) {
+			for (prevbezt=NULL, i=0, bezt=fcu->bezt; i < fcu->totvert; i++, prevbezt=bezt, bezt++) {
 				if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
 					if (v2d->around == V3D_LOCAL) {
 						/* for local-pivot we only need to count the number of selected handles only, so that centerpoitns don't
@@ -3172,13 +3172,12 @@
 						else if (bezt->f2 & SELECT) count++;
 					}
 					else {
-						/* for 'normal' pivots */
-						if (bezt->ipo == BEZT_IPO_BEZ) {
-							if (bezt->f1 & SELECT) count++;
-							if (bezt->f2 & SELECT) count++;
-							if (bezt->f3 & SELECT) count++;
-						}
-						else if (bezt->f2 & SELECT) count++;
+						if ((bezt->f1 & SELECT) ||
+						    ((bezt->f2 & SELECT) && prevbezt && prevbezt->ipo != BEZT_IPO_BEZ))
+							count++;
+						if (bezt->f2 & SELECT) count++;
+						if (bezt->f3 & SELECT)
+							count++;
 					}
 				}
 			}
@@ -3220,38 +3219,36 @@
 				short h1=1, h2=1;
 				
 				/* only include handles if selected, and interpolaton mode uses beztriples */
-				if ( (!prevbezt && (bezt->ipo==BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo==BEZT_IPO_BEZ)) ) {
-					if (bezt->f1 & SELECT) {
-						hdata = initTransDataCurveHandes(td, bezt);
-						bezt_to_transdata(td++, td2d++, nob, bezt->vec[0], bezt->vec[1], 1, 1, intvals);
-					}
-					else
-						h1= 0;
+				if ((bezt->f1 & SELECT) ||
+				    ((bezt->f2 & SELECT) && prevbezt && prevbezt->ipo != BEZT_IPO_BEZ)) {
+					hdata = initTransDataCurveHandles(td, bezt);
+					bezt_to_transdata(td++, td2d++, nob, bezt->vec[0], bezt->vec[1], 1, 1, intvals);
 				}
-				if (bezt->ipo == BEZT_IPO_BEZ) {
-					if (bezt->f3 & SELECT) {
-						if (hdata==NULL)
-							hdata = initTransDataCurveHandes(td, bezt);
-						bezt_to_transdata(td++, td2d++, nob, bezt->vec[2], bezt->vec[1], 1, 1, intvals);
-					}
-					else
-						h2= 0;
+				else if (bezt->ipo == BEZT_IPO_BEZ)
+					h1= 0;
+
+				if (bezt->f3 & SELECT) {
+					if (hdata==NULL)
+						hdata = initTransDataCurveHandles(td, bezt);
+					bezt_to_transdata(td++, td2d++, nob, bezt->vec[2], bezt->vec[1], 1, 1, intvals);
 				}
+				else if (bezt->ipo == BEZT_IPO_BEZ)
+					h2= 0;
 				
 				/* only include main vert if selected */
 				if (bezt->f2 & SELECT) {
-					/* if scaling around individuals centers, do no include keyframes */
+					/* if scaling around individuals centers, do not include keyframes */
 					if (v2d->around != V3D_LOCAL) {
 						/* if handles were not selected, store their selection status */
 						if (!(bezt->f1 & SELECT) && !(bezt->f3 & SELECT)) {
 							if (hdata == NULL)
-								hdata = initTransDataCurveHandes(td, bezt);
+								hdata = initTransDataCurveHandles(td, bezt);
 						}
 						
 						bezt_to_transdata(td++, td2d++, nob, bezt->vec[1], bezt->vec[1], 1, 0, intvals);
 					}
 					
-					/* special hack (must be done after initTransDataCurveHandes(), as that stores handle settings to restore...): 
+					/* special hack (must be done after initTransDataCurveHandles(), as that stores handle settings to restore...): 
 					 *	- Check if we've got entire BezTriple selected and we're scaling/rotating that point, 
 					 *	  then check if we're using auto-handles. 
 					 *	- If so, change them auto-handles to aligned handles so that handles get affected too
@@ -3389,26 +3386,22 @@
 			if (adjusted[j] != 0) continue;
 			
 			/* only selected verts */
-			if (bezm->pipo == BEZT_IPO_BEZ) {
-				if (bezm->bezt->f1 & SELECT) {
-					if (td->loc2d == bezm->bezt->vec[0]) {
-						if (bezm->swapHs == 1)
-							td->loc2d= (bezts + bezm->newIndex)->vec[2];
-						else
-							td->loc2d= (bezts + bezm->newIndex)->vec[0];
-						adjusted[j] = 1;
-					}
+			if (bezm->bezt->f1 & SELECT) {
+				if (td->loc2d == bezm->bezt->vec[0]) {
+					if (bezm->swapHs == 1)
+						td->loc2d= (bezts + bezm->newIndex)->vec[2];
+					else
+						td->loc2d= (bezts + bezm->newIndex)->vec[0];
+					adjusted[j] = 1;
 				}
 			}
-			if (bezm->cipo == BEZT_IPO_BEZ) {
-				if (bezm->bezt->f3 & SELECT) {
-					if (td->loc2d == bezm->bezt->vec[2]) {
-						if (bezm->swapHs == 1)
-							td->loc2d= (bezts + bezm->newIndex)->vec[0];
-						else
-							td->loc2d= (bezts + bezm->newIndex)->vec[2];
-						adjusted[j] = 1;
-					}
+			if (bezm->bezt->f3 & SELECT) {
+				if (td->loc2d == bezm->bezt->vec[2]) {
+					if (bezm->swapHs == 1)
+						td->loc2d= (bezts + bezm->newIndex)->vec[0];
+					else
+						td->loc2d= (bezts + bezm->newIndex)->vec[2];
+					adjusted[j] = 1;
 				}
 			}
 			if (bezm->bezt->f2 & SELECT) {


More information about the Bf-animsys mailing list