[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [35513] trunk/blender/source/blender: Pose Sliding Tools - Custom Property Support + Other bugfixes

Joshua Leung aligorith at gmail.com
Sun Mar 13 13:22:57 CET 2011


Revision: 35513
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=35513
Author:   aligorith
Date:     2011-03-13 12:22:57 +0000 (Sun, 13 Mar 2011)
Log Message:
-----------
Pose Sliding Tools - Custom Property Support + Other bugfixes

- Custom properties are now affected by the Pose Sliding tools too.
This is now more important to support, given that modern rigs use
these a lot for facial expressions/posing. By and large, this should
work fine, though discrete integer values may experience a bit of
trouble

- Fixed potential bugs with the code which detects which F-Curves are
relevant to a PoseBone's transforms (+ custom props). This was prone
to being tricked by certain setups if the names of the bones contained
some of the keywords these were searching for.

- Shuffled some code around: moved bulk of logic out of vec3 case into
new function for single-value, since it was really doing per axis
already

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_action.h
    trunk/blender/source/blender/blenkernel/intern/action.c
    trunk/blender/source/blender/editors/armature/armature_intern.h
    trunk/blender/source/blender/editors/armature/poseSlide.c
    trunk/blender/source/blender/editors/armature/poseUtils.c

Modified: trunk/blender/source/blender/blenkernel/BKE_action.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_action.h	2011-03-13 09:52:49 UTC (rev 35512)
+++ trunk/blender/source/blender/blenkernel/BKE_action.h	2011-03-13 12:22:57 UTC (rev 35513)
@@ -82,9 +82,15 @@
 	ACT_TRANS_ROT	= (1<<1),
 		/* scaling */
 	ACT_TRANS_SCALE	= (1<<2),
+	
+		/* strictly not a transform, but custom properties are also
+		 * quite often used in modern rigs
+		 */
+	ACT_TRANS_PROP 	= (1<<3),
 		
 		/* all flags */
-	ACT_TRANS_ALL	= (ACT_TRANS_LOC|ACT_TRANS_ROT|ACT_TRANS_SCALE),
+	ACT_TRANS_ONLY 	= (ACT_TRANS_LOC|ACT_TRANS_ROT|ACT_TRANS_SCALE),
+	ACT_TRANS_ALL	= (ACT_TRANS_ONLY|ACT_TRANS_PROP)
 } eAction_TransformFlags;
 
 /* Return flags indicating which transforms the given object/posechannel has 

Modified: trunk/blender/source/blender/blenkernel/intern/action.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/action.c	2011-03-13 09:52:49 UTC (rev 35512)
+++ trunk/blender/source/blender/blenkernel/intern/action.c	2011-03-13 12:22:57 UTC (rev 35513)
@@ -973,6 +973,11 @@
 		bPtr= strstr(fcu->rna_path, basePath);
 		
 		if (bPtr) {
+			/* we must add len(basePath) bytes to the match so that we are at the end of the 
+			 * base path so that we don't get false positives with these strings in the names
+			 */
+			bPtr += strlen(basePath);
+			
 			/* step 2: check for some property with transforms 
 			 *	- to speed things up, only check for the ones not yet found 
 			 * 	  unless we're getting the curves too
@@ -981,8 +986,8 @@
 			 *	- once a match has been found, the curve cannot possibly be any other one
 			 */
 			if ((curves) || (flags & ACT_TRANS_LOC) == 0) {
-				pPtr= strstr(fcu->rna_path, "location");
-				if ((pPtr) && (pPtr >= bPtr)) {
+				pPtr= strstr(bPtr, "location");
+				if (pPtr) {
 					flags |= ACT_TRANS_LOC;
 					
 					if (curves) 
@@ -992,8 +997,8 @@
 			}
 			
 			if ((curves) || (flags & ACT_TRANS_SCALE) == 0) {
-				pPtr= strstr(fcu->rna_path, "scale");
-				if ((pPtr) && (pPtr >= bPtr)) {
+				pPtr= strstr(bPtr, "scale");
+				if (pPtr) {
 					flags |= ACT_TRANS_SCALE;
 					
 					if (curves) 
@@ -1003,8 +1008,8 @@
 			}
 			
 			if ((curves) || (flags & ACT_TRANS_ROT) == 0) {
-				pPtr= strstr(fcu->rna_path, "rotation");
-				if ((pPtr) && (pPtr >= bPtr)) {
+				pPtr= strstr(bPtr, "rotation");
+				if (pPtr) {
 					flags |= ACT_TRANS_ROT;
 					
 					if (curves) 
@@ -1012,6 +1017,18 @@
 					continue;
 				}
 			}
+			
+			if ((curves) || (flags & ACT_TRANS_PROP) == 0) {
+				/* custom properties only */
+				pPtr= strstr(bPtr, "[\""); /* extra '"' comment here to keep my texteditor functionlist working :) */  
+				if (pPtr) {
+					flags |= ACT_TRANS_PROP;
+					
+					if (curves)
+						BLI_addtail(curves, BLI_genericNodeN(fcu));
+					continue;
+				}
+			}
 		}
 	}
 	

Modified: trunk/blender/source/blender/editors/armature/armature_intern.h
===================================================================
--- trunk/blender/source/blender/editors/armature/armature_intern.h	2011-03-13 09:52:49 UTC (rev 35512)
+++ trunk/blender/source/blender/editors/armature/armature_intern.h	2011-03-13 12:22:57 UTC (rev 35513)
@@ -150,16 +150,19 @@
 typedef struct tPChanFCurveLink {
 	struct tPChanFCurveLink *next, *prev;
 	
-	ListBase fcurves;			/* F-Curves for this PoseChannel (wrapped with LinkData) */
-	struct bPoseChannel *pchan;	/* Pose Channel which data is attached to */
+	ListBase fcurves;				/* F-Curves for this PoseChannel (wrapped with LinkData) */
+	struct bPoseChannel *pchan;		/* Pose Channel which data is attached to */
 	
-	char *pchan_path;			/* RNA Path to this Pose Channel (needs to be freed when we're done) */
+	char *pchan_path;				/* RNA Path to this Pose Channel (needs to be freed when we're done) */
 	
-		// TODO: need to include axis-angle here at some stage
-	float oldloc[3];			/* transform values at start of operator (to be restored before each modal step) */
+	float oldloc[3];				/* transform values at start of operator (to be restored before each modal step) */
 	float oldrot[3];
 	float oldscale[3];
 	float oldquat[4];
+	float oldangle;
+	float oldaxis[3];
+	
+	struct IDProperty *oldprops;	/* copy of custom properties at start of operator (to be restored before each modal step) */	
 } tPChanFCurveLink;
 
 /* ----------- */

Modified: trunk/blender/source/blender/editors/armature/poseSlide.c
===================================================================
--- trunk/blender/source/blender/editors/armature/poseSlide.c	2011-03-13 09:52:49 UTC (rev 35512)
+++ trunk/blender/source/blender/editors/armature/poseSlide.c	2011-03-13 12:22:57 UTC (rev 35513)
@@ -192,102 +192,146 @@
 	poseAnim_mapping_refresh(C, pso->scene, pso->ob);
 }
 
+/* helper for apply() - perform sliding for some value */
+static void pose_slider_apply_val (tPoseSlideOp *pso, FCurve *fcu, float *val)
+{
+	float cframe = (float)pso->cframe;
+	float sVal, eVal;
+	float w1, w2;
+	
+	/* get keyframe values for endpoint poses to blend with */
+		/* previous/start */
+	sVal= evaluate_fcurve(fcu, (float)pso->prevFrame);
+		/* next/end */
+	eVal= evaluate_fcurve(fcu, (float)pso->nextFrame);
+	
+	/* calculate the relative weights of the endpoints */
+	if (pso->mode == POSESLIDE_BREAKDOWN) {
+		/* get weights from the percentage control */
+		w1= pso->percentage;	/* this must come second */
+		w2= 1.0f - w1;			/* this must come first */
+	}
+	else {
+		/*	- these weights are derived from the relative distance of these 
+		 *	  poses from the current frame
+		 *	- they then get normalised so that they only sum up to 1
+		 */
+		float wtot; 
+		
+		w1 = cframe - (float)pso->prevFrame;
+		w2 = (float)pso->nextFrame - cframe;
+		
+		wtot = w1 + w2;
+		w1 = (w1/wtot);
+		w2 = (w2/wtot);
+	}
+	
+	/* depending on the mode, calculate the new value
+	 *	- in all of these, the start+end values are multiplied by w2 and w1 (respectively),
+	 *	  since multiplication in another order would decrease the value the current frame is closer to
+	 */
+	switch (pso->mode) {
+		case POSESLIDE_PUSH: /* make the current pose more pronounced */
+		{
+			/* perform a weighted average here, favouring the middle pose 
+			 *	- numerator should be larger than denominator to 'expand' the result
+			 *	- perform this weighting a number of times given by the percentage...
+			 */
+			int iters= (int)ceil(10.0f*pso->percentage); // TODO: maybe a sensitivity ctrl on top of this is needed
+			
+			while (iters-- > 0) {
+				(*val)= ( -((sVal * w2) + (eVal * w1)) + ((*val) * 6.0f) ) / 5.0f; 
+			}
+		}
+			break;
+			
+		case POSESLIDE_RELAX: /* make the current pose more like its surrounding ones */
+		{
+			/* perform a weighted average here, favouring the middle pose 
+			 *	- numerator should be smaller than denominator to 'relax' the result
+			 *	- perform this weighting a number of times given by the percentage...
+			 */
+			int iters= (int)ceil(10.0f*pso->percentage); // TODO: maybe a sensitivity ctrl on top of this is needed
+			
+			while (iters-- > 0) {
+				(*val)= ( ((sVal * w2) + (eVal * w1)) + ((*val) * 5.0f) ) / 6.0f;
+			}
+		}
+			break;
+			
+		case POSESLIDE_BREAKDOWN: /* make the current pose slide around between the endpoints */
+		{
+			/* perform simple linear interpolation - coefficient for start must come from pso->percentage... */
+			// TODO: make this use some kind of spline interpolation instead?
+			(*val)= ((sVal * w2) + (eVal * w1));
+		}
+			break;
+	}
+}
+
 /* helper for apply() - perform sliding for some 3-element vector */
-static void pose_slide_apply_vec3 (tPoseSlideOp *pso, tPChanFCurveLink *pfl, float vec[3], const char *propName)
+static void pose_slide_apply_vec3 (tPoseSlideOp *pso, tPChanFCurveLink *pfl, float vec[3], const char propName[])
 {
 	LinkData *ld=NULL;
 	char *path=NULL;
-	float cframe;
 	
 	/* get the path to use... */
 	path= BLI_sprintfN("%s.%s", pfl->pchan_path, propName);
 	
-	/* get the current frame number */
-	cframe= (float)pso->cframe;
-	
 	/* using this path, find each matching F-Curve for the variables we're interested in */
 	while ( (ld= poseAnim_mapping_getNextFCurve(&pfl->fcurves, ld, path)) ) {
 		FCurve *fcu= (FCurve *)ld->data;
-		float sVal, eVal;
-		float w1, w2;
-		int ch;
 		
-		/* get keyframe values for endpoint poses to blend with */
-			/* previous/start */
-		sVal= evaluate_fcurve(fcu, (float)pso->prevFrame);
-			/* next/end */
-		eVal= evaluate_fcurve(fcu, (float)pso->nextFrame);
+		/* just work on these channels one by one... there's no interaction between values */
+		pose_slider_apply_val(pso, fcu, &vec[fcu->array_index]);
+	}
+	
+	/* free the temp path we got */
+	MEM_freeN(path);
+}
+
+/* helper for apply() - perform sliding for custom properties */
+static void pose_slide_apply_props (tPoseSlideOp *pso, tPChanFCurveLink *pfl)
+{
+	PointerRNA ptr = {{NULL}};
+	LinkData *ld;
+	int len = strlen(pfl->pchan_path);
+	
+	/* setup pointer RNA for resolving paths */
+	RNA_pointer_create(NULL, &RNA_PoseBone, pfl->pchan, &ptr);
+	
+	/* custom properties are just denoted using ["..."][etc.] after the end of the base path, 
+	 * so just check for opening pair after the end of the path
+	 */
+	for (ld = pfl->fcurves.first; ld; ld = ld->next) {
+		FCurve *fcu = (FCurve *)ld->data;
+		char *bPtr, *pPtr;
 		
-		/* get channel index */
-		ch= fcu->array_index;
+		if (fcu->rna_path == NULL)
+			continue;
 		
-		/* calculate the relative weights of the endpoints */
-		if (pso->mode == POSESLIDE_BREAKDOWN) {
-			/* get weights from the percentage control */
-			w1= pso->percentage;	/* this must come second */
-			w2= 1.0f - w1;			/* this must come first */
-		}
-		else {
-			/*	- these weights are derived from the relative distance of these 
-			 *	  poses from the current frame
-			 *	- they then get normalised so that they only sum up to 1
+		/* do we have a match? 
+		 *	- bPtr is the RNA Path with the standard part chopped off
+		 *	- pPtr is the chunk of the path which is left over
+		 */
+		bPtr = strstr(fcu->rna_path, pfl->pchan_path) + len;
+		pPtr = strstr(bPtr, "[\"");   /* dummy " for texteditor bugs */
+		
+		if (pPtr) {
+			/* use RNA to try and get a handle on this property, then, assuming that it is just
+			 * numerical, try and grab the value as a float for temp editing before setting back
 			 */
-			float wtot; 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list